diff --git a/shared/lib/scores.ts b/shared/lib/scores.ts index 39fc53bc..d225f9f8 100644 --- a/shared/lib/scores.ts +++ b/shared/lib/scores.ts @@ -1,7 +1,11 @@ // ======================================== // Score Systems Integration // ======================================== -// Centralized score fetching from blockchain pallets +// All scores come from People Chain (people-rpc.pezkuwichain.io) +// - Trust Score: pezpallet-trust +// - Referral Score: pezpallet-referral +// - Staking Score: pezpallet-staking-score +// - Tiki Score: pezpallet-tiki import type { ApiPromise } from '@pezkuwi/api'; @@ -13,39 +17,35 @@ export interface UserScores { trustScore: number; referralScore: number; stakingScore: number; - lpStakingScore: number; tikiScore: number; totalScore: number; } -export interface TrustScoreDetails { - totalScore: number; - stakingPoints: number; - referralPoints: number; - tikiPoints: number; - activityPoints: number; - historyLength: number; +export interface StakingScoreStatus { + isTracking: boolean; + startBlock: number | null; + currentBlock: number; + durationBlocks: number; } // ======================================== -// TRUST SCORE (pallet_trust) +// TRUST SCORE (pezpallet-trust on People Chain) // ======================================== /** * Fetch user's trust score from blockchain - * pallet_trust::TrustScores storage + * Storage: trust.trustScores(address) */ export async function getTrustScore( - api: ApiPromise, + peopleApi: ApiPromise, address: string ): Promise { try { - if (!api?.query?.trust) { - // Trust pallet not available on this chain - this is expected + if (!peopleApi?.query?.trust?.trustScores) { return 0; } - const score = await api.query.trust.trustScores(address); + const score = await peopleApi.query.trust.trustScores(address); if (score.isEmpty) { return 0; @@ -58,101 +58,36 @@ export async function getTrustScore( } } -/** - * Fetch detailed trust score breakdown - * pallet_trust::ScoreHistory storage - */ -export async function getTrustScoreDetails( - api: ApiPromise, - address: string -): Promise { - try { - if (!api?.query?.trust) { - return null; - } - - const totalScore = await getTrustScore(api, address); - - // Get score history to show detailed breakdown - const historyResult = await api.query.trust.scoreHistory(address); - - if (historyResult.isEmpty) { - return { - totalScore, - stakingPoints: 0, - referralPoints: 0, - tikiPoints: 0, - activityPoints: 0, - historyLength: 0 - }; - } - - const history = historyResult.toJSON() as any[]; - - // Calculate points from history - // History format: [{blockNumber, score, reason}] - let stakingPoints = 0; - let referralPoints = 0; - let tikiPoints = 0; - let activityPoints = 0; - - for (const entry of history) { - const reason = entry.reason || ''; - const score = entry.score || 0; - - if (reason.includes('Staking')) stakingPoints += score; - else if (reason.includes('Referral')) referralPoints += score; - else if (reason.includes('Tiki') || reason.includes('Role')) tikiPoints += score; - else activityPoints += score; - } - - return { - totalScore, - stakingPoints, - referralPoints, - tikiPoints, - activityPoints, - historyLength: history.length - }; - } catch (error) { - console.error('Error fetching trust score details:', error); - return null; - } -} - // ======================================== -// REFERRAL SCORE (pallet_trust) +// REFERRAL SCORE (pezpallet-referral on People Chain) // ======================================== /** - * Fetch user's referral score - * Reads from pallet_referral::ReferralCount storage + * Fetch user's referral count and calculate score + * Storage: referral.referralCount(address) * - * Score calculation based on referral count: + * Score calculation: * - 0 referrals: 0 points - * - 1-5 referrals: count × 4 points (4, 8, 12, 16, 20) + * - 1-5 referrals: count × 4 points * - 6-20 referrals: 20 + (count - 5) × 2 points * - 21+ referrals: capped at 50 points */ export async function getReferralScore( - api: ApiPromise, + peopleApi: ApiPromise, address: string ): Promise { try { - if (!api?.query?.referral?.referralCount) { - if (typeof __DEV__ !== 'undefined' && __DEV__) console.warn('Referral pallet not available'); + if (!peopleApi?.query?.referral?.referralCount) { return 0; } - const count = await api.query.referral.referralCount(address); + const count = await peopleApi.query.referral.referralCount(address); const referralCount = Number(count.toString()); - // Calculate score based on referral count if (referralCount === 0) return 0; if (referralCount <= 5) return referralCount * 4; if (referralCount <= 20) return 20 + ((referralCount - 5) * 2); return 50; // Capped at 50 points - } catch (error) { console.error('Error fetching referral score:', error); return 0; @@ -160,26 +95,19 @@ export async function getReferralScore( } /** - * Get referral count for user - * pallet_trust::Referrals storage + * Get raw referral count */ export async function getReferralCount( - api: ApiPromise, + peopleApi: ApiPromise, address: string ): Promise { try { - if (!api?.query?.trust?.referrals) { + if (!peopleApi?.query?.referral?.referralCount) { return 0; } - const referrals = await api.query.trust.referrals(address); - - if (referrals.isEmpty) { - return 0; - } - - const referralList = referrals.toJSON() as any[]; - return Array.isArray(referralList) ? referralList.length : 0; + const count = await peopleApi.query.referral.referralCount(address); + return Number(count.toString()); } catch (error) { console.error('Error fetching referral count:', error); return 0; @@ -187,86 +115,103 @@ export async function getReferralCount( } // ======================================== -// STAKING SCORE (pallet_staking_score) +// STAKING SCORE (pezpallet-staking-score on People Chain) // ======================================== /** - * Get staking score from pallet_staking_score - * NOTE: stakingScore pallet is on People Chain, but staking.ledger is on Relay Chain - * So this function needs both APIs - * - * @param peopleApi - API for People Chain (stakingScore pallet) - * @param relayApi - API for Relay Chain (staking pallet) - optional, if not provided uses peopleApi + * Check staking score tracking status + * Storage: stakingScore.stakingStartBlock(address) */ -export async function getStakingScoreFromPallet( +export async function getStakingScoreStatus( + peopleApi: ApiPromise, + address: string +): Promise { + try { + if (!peopleApi?.query?.stakingScore?.stakingStartBlock) { + return { isTracking: false, startBlock: null, currentBlock: 0, durationBlocks: 0 }; + } + + const startBlockResult = await peopleApi.query.stakingScore.stakingStartBlock(address); + const currentBlock = Number((await peopleApi.query.system.number()).toString()); + + if (startBlockResult.isEmpty || startBlockResult.isNone) { + return { isTracking: false, startBlock: null, currentBlock, durationBlocks: 0 }; + } + + const startBlock = Number(startBlockResult.toString()); + const durationBlocks = currentBlock - startBlock; + + return { + isTracking: true, + startBlock, + currentBlock, + durationBlocks + }; + } catch (error) { + console.error('Error fetching staking score status:', error); + return { isTracking: false, startBlock: null, currentBlock: 0, durationBlocks: 0 }; + } +} + +/** + * Get staking score from pallet + * Requires: User must have called startScoreTracking() first + * Score based on staking duration + amount staked on Relay Chain + * + * @param peopleApi - People Chain API (stakingScore pallet) + * @param address - User's blockchain address + * @param relayApi - Relay Chain API (staking.ledger for staked amount) + */ +export async function getStakingScore( peopleApi: ApiPromise, address: string, relayApi?: ApiPromise ): Promise { try { - if (!peopleApi?.query?.stakingScore) { - // Staking score pallet not available on this chain - return 0; + const status = await getStakingScoreStatus(peopleApi, address); + + if (!status.isTracking) { + return 0; // User hasn't started score tracking } - // Check if user has started score tracking (People Chain) - const scoreResult = await peopleApi.query.stakingScore.stakingStartBlock(address); - - if (scoreResult.isNone) { - return 0; + // Get staked amount from Relay Chain if available + let stakedAmount = 0; + if (relayApi?.query?.staking?.ledger) { + const ledger = await relayApi.query.staking.ledger(address); + if (!ledger.isEmpty && !ledger.isNone) { + const ledgerData = (ledger as any).unwrap().toJSON(); + stakedAmount = Number(ledgerData.total || 0) / 1e12; + } } - // Get staking info from staking pallet (Relay Chain) - const stakingApi = relayApi || peopleApi; - if (!stakingApi?.query?.staking?.ledger) { - // Staking pallet not available - can't calculate full score - // Return base score from duration only - const scoreCodec = scoreResult.unwrap() as { toString: () => string }; - const startBlock = Number(scoreCodec.toString()); - const currentBlock = Number((await peopleApi.query.system.number()).toString()); - const durationInBlocks = currentBlock - startBlock; - - const MONTH_IN_BLOCKS = 30 * 24 * 60 * 10; - if (durationInBlocks >= 12 * MONTH_IN_BLOCKS) return 40; - if (durationInBlocks >= 6 * MONTH_IN_BLOCKS) return 34; - if (durationInBlocks >= 3 * MONTH_IN_BLOCKS) return 28; - if (durationInBlocks >= MONTH_IN_BLOCKS) return 24; - return 20; + // Calculate score based on amount + // Amount-based score (0-50 points) + let amountScore = 0; + if (stakedAmount > 0) { + if (stakedAmount <= 10) amountScore = 10; + else if (stakedAmount <= 100) amountScore = 20; + else if (stakedAmount <= 250) amountScore = 30; + else if (stakedAmount <= 750) amountScore = 40; + else amountScore = 50; } - const ledger = await stakingApi.query.staking.ledger(address); - - if (ledger.isNone) { - return 0; - } - - const ledgerCodec = ledger.unwrap() as { toJSON: () => unknown }; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const ledgerData = ledgerCodec.toJSON() as any; - const stakedAmount = Number(ledgerData.total || 0) / 1e12; // Convert to HEZ - - // Get duration from People Chain - const scoreCodec = scoreResult.unwrap() as { toString: () => string }; - const startBlock = Number(scoreCodec.toString()); - const currentBlock = Number((await peopleApi.query.system.number()).toString()); - const durationInBlocks = currentBlock - startBlock; - - // Calculate score based on amount and duration - // Amount-based score (20-50 points) - let amountScore = 20; - if (stakedAmount <= 100) amountScore = 20; - else if (stakedAmount <= 250) amountScore = 30; - else if (stakedAmount <= 750) amountScore = 40; - else amountScore = 50; - // Duration multiplier - const MONTH_IN_BLOCKS = 30 * 24 * 60 * 10; // ~30 days + const MONTH_IN_BLOCKS = 30 * 24 * 60 * 10; // ~432000 blocks per month let durationMultiplier = 1.0; - if (durationInBlocks >= 12 * MONTH_IN_BLOCKS) durationMultiplier = 2.0; - else if (durationInBlocks >= 6 * MONTH_IN_BLOCKS) durationMultiplier = 1.7; - else if (durationInBlocks >= 3 * MONTH_IN_BLOCKS) durationMultiplier = 1.4; - else if (durationInBlocks >= MONTH_IN_BLOCKS) durationMultiplier = 1.2; + if (status.durationBlocks >= 12 * MONTH_IN_BLOCKS) durationMultiplier = 2.0; + else if (status.durationBlocks >= 6 * MONTH_IN_BLOCKS) durationMultiplier = 1.7; + else if (status.durationBlocks >= 3 * MONTH_IN_BLOCKS) durationMultiplier = 1.4; + else if (status.durationBlocks >= MONTH_IN_BLOCKS) durationMultiplier = 1.2; + + // If no staking amount but tracking is active, give base points for duration + if (amountScore === 0 && status.isTracking) { + if (status.durationBlocks >= 12 * MONTH_IN_BLOCKS) return 20; + if (status.durationBlocks >= 6 * MONTH_IN_BLOCKS) return 15; + if (status.durationBlocks >= 3 * MONTH_IN_BLOCKS) return 10; + if (status.durationBlocks >= MONTH_IN_BLOCKS) return 5; + return 0; + } return Math.min(100, Math.floor(amountScore * durationMultiplier)); } catch (error) { @@ -275,83 +220,59 @@ export async function getStakingScoreFromPallet( } } -// ======================================== -// LP STAKING SCORE (Asset Hub assetRewards pallet) -// ======================================== - /** - * Get LP staking score from Asset Hub - * Based on total LP tokens staked across all pools - * - * @param assetHubApi - API for Asset Hub (assetRewards pallet) - * @param address - User's blockchain address + * Start staking score tracking + * Calls: stakingScore.startScoreTracking() */ -export async function getLpStakingScore( - assetHubApi: ApiPromise, - address: string -): Promise { +export async function startScoreTracking( + peopleApi: ApiPromise, + address: string, + signer: any +): Promise<{ success: boolean; error?: string }> { try { - if (!assetHubApi?.query?.assetRewards?.poolStakers) { - return 0; + if (!peopleApi?.tx?.stakingScore?.startScoreTracking) { + return { success: false, error: 'stakingScore pallet not available' }; } - // Query all staking pool entries - const poolEntries = await assetHubApi.query.assetRewards.pools.entries(); + const tx = peopleApi.tx.stakingScore.startScoreTracking(); - let totalStaked = BigInt(0); - - for (const [key] of poolEntries) { - const poolId = parseInt(key.args[0].toString()); - - try { - const stakeInfo = await assetHubApi.query.assetRewards.poolStakers([poolId, address]); - if (stakeInfo && (stakeInfo as { isSome: boolean }).isSome) { - const stakeData = (stakeInfo as { unwrap: () => { toJSON: () => { amount: string } } }).unwrap().toJSON(); - totalStaked += BigInt(stakeData.amount || '0'); + return new Promise((resolve) => { + tx.signAndSend(address, { signer }, ({ status, dispatchError }) => { + if (status.isInBlock || status.isFinalized) { + if (dispatchError) { + if (dispatchError.isModule) { + const decoded = peopleApi.registry.findMetaError(dispatchError.asModule); + resolve({ success: false, error: `${decoded.section}.${decoded.name}: ${decoded.docs.join(' ')}` }); + } else { + resolve({ success: false, error: dispatchError.toString() }); + } + } else { + resolve({ success: true }); + } } - } catch { - // Skip this pool on error - } - } - - // Convert to human readable (12 decimals for LP tokens) - const stakedAmount = Number(totalStaked) / 1e12; - - // Calculate score based on amount staked - // 0-10 LP: 0 points - // 10-50 LP: 10 points - // 50-100 LP: 20 points - // 100-500 LP: 30 points - // 500-1000 LP: 40 points - // 1000+ LP: 50 points - if (stakedAmount < 10) return 0; - if (stakedAmount < 50) return 10; - if (stakedAmount < 100) return 20; - if (stakedAmount < 500) return 30; - if (stakedAmount < 1000) return 40; - return 50; + }); + }); } catch (error) { - console.error('Error fetching LP staking score:', error); - return 0; + console.error('Error starting score tracking:', error); + return { success: false, error: error instanceof Error ? error.message : 'Unknown error' }; } } // ======================================== -// TIKI SCORE (from lib/tiki.ts) +// TIKI SCORE (pezpallet-tiki on People Chain) // ======================================== -/** - * Calculate Tiki score from user's roles - * Import from lib/tiki.ts - */ import { fetchUserTikis, calculateTikiScore } from './tiki'; +/** + * Get tiki score from user's roles + */ export async function getTikiScore( - api: ApiPromise, + peopleApi: ApiPromise, address: string ): Promise { try { - const tikis = await fetchUserTikis(api, address); + const tikis = await fetchUserTikis(peopleApi, address); return calculateTikiScore(tikis); } catch (error) { console.error('Error fetching tiki score:', error); @@ -365,17 +286,16 @@ export async function getTikiScore( /** * Fetch all scores for a user in one call + * All scores come from People Chain except staking amount (Relay Chain) * - * @param peopleApi - API for People Chain (trust, referral, tiki, stakingScore pallets) + * @param peopleApi - People Chain API (trust, referral, stakingScore, tiki pallets) * @param address - User's blockchain address - * @param relayApi - Optional API for Relay Chain (staking pallet for validator staking score) - * @param assetHubApi - Optional API for Asset Hub (assetRewards pallet for LP staking score) + * @param relayApi - Optional Relay Chain API (for staking.ledger amount) */ export async function getAllScores( peopleApi: ApiPromise, address: string, - relayApi?: ApiPromise, - assetHubApi?: ApiPromise + relayApi?: ApiPromise ): Promise { try { if (!peopleApi || !address) { @@ -383,31 +303,25 @@ export async function getAllScores( trustScore: 0, referralScore: 0, stakingScore: 0, - lpStakingScore: 0, tikiScore: 0, totalScore: 0 }; } - // Fetch all scores in parallel - // - Trust, referral, tiki scores: People Chain - // - Staking score: People Chain (stakingScore pallet) + Relay Chain (staking.ledger) - // - LP Staking score: Asset Hub (assetRewards pallet) - const [trustScore, referralScore, stakingScore, lpStakingScore, tikiScore] = await Promise.all([ + // Fetch all scores in parallel from People Chain + const [trustScore, referralScore, stakingScore, tikiScore] = await Promise.all([ getTrustScore(peopleApi, address), getReferralScore(peopleApi, address), - getStakingScoreFromPallet(peopleApi, address, relayApi), - assetHubApi ? getLpStakingScore(assetHubApi, address) : Promise.resolve(0), + getStakingScore(peopleApi, address, relayApi), getTikiScore(peopleApi, address) ]); - const totalScore = trustScore + referralScore + stakingScore + lpStakingScore + tikiScore; + const totalScore = trustScore + referralScore + stakingScore + tikiScore; return { trustScore, referralScore, stakingScore, - lpStakingScore, tikiScore, totalScore }; @@ -417,7 +331,6 @@ export async function getAllScores( trustScore: 0, referralScore: 0, stakingScore: 0, - lpStakingScore: 0, tikiScore: 0, totalScore: 0 }; @@ -428,9 +341,6 @@ export async function getAllScores( // SCORE DISPLAY HELPERS // ======================================== -/** - * Get color class based on score - */ export function getScoreColor(score: number): string { if (score >= 200) return 'text-purple-500'; if (score >= 150) return 'text-pink-500'; @@ -441,9 +351,6 @@ export function getScoreColor(score: number): string { return 'text-gray-500'; } -/** - * Get score rating label - */ export function getScoreRating(score: number): string { if (score >= 250) return 'Legendary'; if (score >= 200) return 'Excellent'; @@ -455,9 +362,19 @@ export function getScoreRating(score: number): string { return 'Very Low'; } -/** - * Format score for display - */ export function formatScore(score: number): string { return score.toFixed(0); } + +export function formatDuration(blocks: number): string { + const BLOCKS_PER_MINUTE = 10; + const minutes = blocks / BLOCKS_PER_MINUTE; + const hours = minutes / 60; + const days = hours / 24; + const months = days / 30; + + if (months >= 1) return `${Math.floor(months)} month${Math.floor(months) > 1 ? 's' : ''}`; + if (days >= 1) return `${Math.floor(days)} day${Math.floor(days) > 1 ? 's' : ''}`; + if (hours >= 1) return `${Math.floor(hours)} hour${Math.floor(hours) > 1 ? 's' : ''}`; + return `${Math.floor(minutes)} minute${Math.floor(minutes) > 1 ? 's' : ''}`; +} diff --git a/web/src/pages/Dashboard.tsx b/web/src/pages/Dashboard.tsx index 1562c74c..a5976046 100644 --- a/web/src/pages/Dashboard.tsx +++ b/web/src/pages/Dashboard.tsx @@ -7,10 +7,11 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { useAuth } from '@/contexts/AuthContext'; import { usePezkuwi } from '@/contexts/PezkuwiContext'; import { supabase } from '@/lib/supabase'; -import { User, Mail, Phone, Globe, MapPin, Calendar, Shield, AlertCircle, ArrowLeft, Award, Users, TrendingUp, UserMinus, Coins } from 'lucide-react'; +import { User, Mail, Phone, Globe, MapPin, Calendar, Shield, AlertCircle, ArrowLeft, Award, Users, TrendingUp, UserMinus, Play, Loader2 } from 'lucide-react'; import { useToast } from '@/hooks/use-toast'; import { fetchUserTikis, getPrimaryRole, getTikiDisplayName, getTikiColor, getTikiEmoji, getUserRoleCategories, getAllTikiNFTDetails, generateCitizenNumber, type TikiNFTDetails } from '@pezkuwi/lib/tiki'; -import { getAllScores, type UserScores } from '@pezkuwi/lib/scores'; +import { getAllScores, getStakingScoreStatus, startScoreTracking, type UserScores, type StakingScoreStatus, formatDuration } from '@pezkuwi/lib/scores'; +import { web3FromAddress } from '@pezkuwi/extension-dapp'; import { getKycStatus } from '@pezkuwi/lib/kyc'; import { ReferralDashboard } from '@/components/referral/ReferralDashboard'; // Commission proposals card removed - no longer using notary system for KYC approval @@ -18,7 +19,7 @@ import { ReferralDashboard } from '@/components/referral/ReferralDashboard'; export default function Dashboard() { const { user } = useAuth(); - const { api, isApiReady, peopleApi, isPeopleReady, assetHubApi, isAssetHubReady, selectedAccount } = usePezkuwi(); + const { api, isApiReady, peopleApi, isPeopleReady, selectedAccount } = usePezkuwi(); const navigate = useNavigate(); const { toast } = useToast(); const [profile, setProfile] = useState | null>(null); @@ -28,11 +29,12 @@ export default function Dashboard() { trustScore: 0, referralScore: 0, stakingScore: 0, - lpStakingScore: 0, tikiScore: 0, totalScore: 0 }); const [loadingScores, setLoadingScores] = useState(false); + const [stakingStatus, setStakingStatus] = useState(null); + const [startingScoreTracking, setStartingScoreTracking] = useState(false); const [kycStatus, setKycStatus] = useState('NotStarted'); const [renouncingCitizenship, setRenouncingCitizenship] = useState(false); const [nftDetails, setNftDetails] = useState<{ citizenNFT: TikiNFTDetails | null; roleNFTs: TikiNFTDetails[]; totalNFTs: number }>({ @@ -106,13 +108,16 @@ export default function Dashboard() { setLoadingScores(true); try { - // Fetch all scores from blockchain (includes trust, referral, staking, lpStaking, tiki) - // - Trust, referral, tiki: People Chain - // - Staking score: People Chain (stakingScore pallet) + Relay Chain (staking.ledger) - // - LP Staking score: Asset Hub (assetRewards pallet) - const allScores = await getAllScores(peopleApi, selectedAccount.address, api, assetHubApi || undefined); + // Fetch all scores from blockchain (includes trust, referral, staking, tiki) + // - Trust, referral, tiki, stakingScore: People Chain + // - Staking amount: Relay Chain (staking.ledger) + const allScores = await getAllScores(peopleApi, selectedAccount.address, api); setScores(allScores); + // Fetch staking score tracking status + const stakingStatusResult = await getStakingScoreStatus(peopleApi, selectedAccount.address); + setStakingStatus(stakingStatusResult); + // Fetch tikis from People Chain (tiki pallet is on People Chain) const userTikis = await fetchUserTikis(peopleApi, selectedAccount.address); setTikis(userTikis); @@ -122,21 +127,62 @@ export default function Dashboard() { setNftDetails(details); // Fetch KYC status from People Chain (identityKyc pallet is on People Chain) - const status = await getKycStatus(peopleApi, selectedAccount.address); - setKycStatus(status); + const kycStatusResult = await getKycStatus(peopleApi, selectedAccount.address); + setKycStatus(kycStatusResult); } catch (error) { if (import.meta.env.DEV) console.error('Error fetching scores and tikis:', error); } finally { setLoadingScores(false); } - }, [selectedAccount, api, peopleApi, assetHubApi]); + }, [selectedAccount, api, peopleApi]); + + const handleStartScoreTracking = async () => { + if (!peopleApi || !selectedAccount) { + toast({ + title: "Hata", + description: "Lütfen önce cüzdanınızı bağlayın", + variant: "destructive" + }); + return; + } + + setStartingScoreTracking(true); + try { + const injector = await web3FromAddress(selectedAccount.address); + const result = await startScoreTracking(peopleApi, selectedAccount.address, injector.signer); + + if (result.success) { + toast({ + title: "Başarılı", + description: "Score tracking başlatıldı! Staking score'unuz artık hesaplanacak." + }); + // Refresh scores after starting tracking + fetchScoresAndTikis(); + } else { + toast({ + title: "Hata", + description: result.error || "Score tracking başlatılamadı", + variant: "destructive" + }); + } + } catch (error) { + if (import.meta.env.DEV) console.error('Error starting score tracking:', error); + toast({ + title: "Hata", + description: error instanceof Error ? error.message : "Score tracking başlatılamadı", + variant: "destructive" + }); + } finally { + setStartingScoreTracking(false); + } + }; useEffect(() => { fetchProfile(); - if (selectedAccount && api && isApiReady && peopleApi && isPeopleReady && assetHubApi && isAssetHubReady) { + if (selectedAccount && api && isApiReady && peopleApi && isPeopleReady) { fetchScoresAndTikis(); } - }, [user, selectedAccount, api, isApiReady, peopleApi, isPeopleReady, assetHubApi, isAssetHubReady, fetchProfile, fetchScoresAndTikis]); + }, [user, selectedAccount, api, isApiReady, peopleApi, isPeopleReady, fetchProfile, fetchScoresAndTikis]); const sendVerificationEmail = async () => { if (!user?.email) { @@ -435,24 +481,35 @@ export default function Dashboard() {
{loadingScores ? '...' : scores.stakingScore}
-

- Validator staking -

- - - - - - LP Staking Score - - - -
- {loadingScores ? '...' : scores.lpStakingScore} -
-

- LP token staking -

+ {stakingStatus?.isTracking ? ( +

+ Tracking: {formatDuration(stakingStatus.durationBlocks)} +

+ ) : selectedAccount ? ( + + ) : ( +

+ Connect wallet to track +

+ )}