diff --git a/backend/leaderboard/views.py b/backend/leaderboard/views.py index 0a8727c6..94030cf8 100644 --- a/backend/leaderboard/views.py +++ b/backend/leaderboard/views.py @@ -102,6 +102,16 @@ def get_queryset(self): # Default to validator leaderboard only when not filtering by user queryset = queryset.filter(type='validator') + # Handle network filtering for validators + # Include validators with wallets on the specified network. + # For asimov (default network), also include validators with no wallets. + network = self.request.query_params.get('network') + if network and leaderboard_type == 'validator': + network_q = Q(user__validator__validator_wallets__network=network) + if network == 'asimov': + network_q = network_q | ~Q(user__validator__validator_wallets__isnull=False) + queryset = queryset.filter(network_q).distinct() + # Handle rank ordering order = self.request.query_params.get('order', 'asc') if order == 'desc': diff --git a/frontend/src/components/GlobalDashboard.svelte b/frontend/src/components/GlobalDashboard.svelte index 9c85b490..2a555e7c 100644 --- a/frontend/src/components/GlobalDashboard.svelte +++ b/frontend/src/components/GlobalDashboard.svelte @@ -4,7 +4,7 @@ import { format } from "date-fns"; import TopLeaderboard from "./TopLeaderboard.svelte"; import CategoryIcon from "./portal/CategoryIcon.svelte"; - import { leaderboardAPI, validatorsAPI, statsAPI } from "../lib/api"; + import { leaderboardAPI, validatorsAPI } from "../lib/api"; import { showError } from "../lib/toastStore"; // State management @@ -24,29 +24,27 @@ asimovLeaderboardRes, bradburyLeaderboardRes, waitlistLeaderboardRes, - validatorStatsRes, networksRes, ] = await Promise.all([ leaderboardAPI.getLeaderboardByType("validator", "asc", { - limit: 5, network: "asimov", }), leaderboardAPI.getLeaderboardByType("validator", "asc", { - limit: 5, network: "bradbury", }), leaderboardAPI.getWaitlistTop(5), - statsAPI.getDashboardStats("validator"), validatorsAPI.getNetworks().catch(() => ({ data: [] })), // Handle if not found ]); - // Process leaderboards - asimovLeaderboard = Array.isArray(asimovLeaderboardRes.data) + // Process leaderboards — full list for count, top 5 for display + const asimovFull = Array.isArray(asimovLeaderboardRes.data) ? asimovLeaderboardRes.data : []; - bradburyLeaderboard = Array.isArray(bradburyLeaderboardRes.data) + const bradburyFull = Array.isArray(bradburyLeaderboardRes.data) ? bradburyLeaderboardRes.data : []; + asimovLeaderboard = asimovFull.slice(0, 5); + bradburyLeaderboard = bradburyFull.slice(0, 5); waitlistLeaderboard = Array.isArray(waitlistLeaderboardRes.data) ? waitlistLeaderboardRes.data : []; @@ -68,11 +66,10 @@ bradbury.explorer_url = "https://explorer-bradbury.genlayer.com/"; networks = [asimov, bradbury]; - // Validator count from leaderboard stats — same source as Validators page - const validatorCount = validatorStatsRes.data?.participant_count || 0; + // Validator count per network from leaderboard entries (active on-chain validators) networkStats = { - asimov: { total: validatorCount }, - bradbury: { total: 0 }, + asimov: { total: asimovFull.length }, + bradbury: { total: bradburyFull.length }, }; loading = false; @@ -243,7 +240,7 @@ style="letter-spacing: -0.96px;" >{networkStats.asimov.total} - Validators + Active Validators