diff --git a/nym-wallet/src-tauri/src/operations/mixnet/delegate.rs b/nym-wallet/src-tauri/src/operations/mixnet/delegate.rs index 744aeb1bb7..8fc47187d0 100644 --- a/nym-wallet/src-tauri/src/operations/mixnet/delegate.rs +++ b/nym-wallet/src-tauri/src/operations/mixnet/delegate.rs @@ -407,14 +407,22 @@ pub async fn get_all_mix_delegations( d.height ); let timestamp = client - .nyxd - .get_block_timestamp(Some(d.height as u32)) - .await - .tap_err(|err| { + .nyxd + .get_block_timestamp(Some(d.height as u32)) + .await + .tap_err(|err| { + let error_message = err.to_string(); + // Check if the error is related to height not being available (pruning) + if error_message.contains("height") && error_message.contains("not available") { + let str_err = "Due to pruning strategies from validators, please navigate to the Settings tab and change your RPC node for your validator to retrieve your delegations."; + log::error!(" <<< {}", str_err); + error_strings.push(str_err.to_string()); + } else { let str_err = format!("Failed to get block timestamp for height = {} for delegation to mix_id = {}. Error: {}", d.height, d.mix_id, err); log::error!(" <<< {}", str_err); error_strings.push(str_err); - }).ok(); + } + }).ok(); let delegated_on_iso_datetime = timestamp.map(|ts| ts.to_rfc3339()); log::trace!( " <<< timestamp = {:?}, delegated_on_iso_datetime = {:?}", diff --git a/nym-wallet/src/components/Delegation/DelegationList.tsx b/nym-wallet/src/components/Delegation/DelegationList.tsx index ebda436025..776a412e6b 100644 --- a/nym-wallet/src/components/Delegation/DelegationList.tsx +++ b/nym-wallet/src/components/Delegation/DelegationList.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Box, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, TableSortLabel } from '@mui/material'; +import { Alert, AlertTitle, Box, Button, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, TableSortLabel, Typography } from '@mui/material'; import { visuallyHidden } from '@mui/utils'; import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown'; import { DelegationWithEverything } from '@nymproject/types'; @@ -10,6 +10,7 @@ import { PendingDelegationItem } from './PendingDelegationItem'; import { LoadingModal } from '../Modals/LoadingModal'; import { isDelegation, isPendingDelegation, TDelegations, useDelegationContext } from '../../context/delegations'; import { ErrorModal } from '../Modals/ErrorModal'; +import { useNavigate } from 'react-router-dom'; export type Order = 'asc' | 'desc'; type AdditionalTypes = { profit_margin_percent: number; operating_cost: number }; @@ -83,7 +84,15 @@ const EnhancedTableHead: FCWithChildren = ({ order, orderBy, ); }; -// Pin delegations on unbonded nodes to the top of the list +const hasPruningError = (item: any): boolean => { + if (!isDelegation(item) || !item.errors) return false; + + return ( + item.errors.includes("height") && + item.errors.includes("not available") || + item.errors.includes("Due to pruning strategies") + ); +}; export const DelegationList: FCWithChildren<{ isLoading?: boolean; @@ -94,6 +103,7 @@ export const DelegationList: FCWithChildren<{ }> = ({ isLoading, items, onItemActionClick, explorerUrl }) => { const [order, setOrder] = React.useState('asc'); const [orderBy, setOrderBy] = React.useState('delegated_on_iso_datetime'); + const navigate = useNavigate(); const { delegationItemErrors, setDelegationItemErrors } = useDelegationContext(); @@ -104,36 +114,83 @@ export const DelegationList: FCWithChildren<{ }; const sorted = useSortDelegations(items, order, orderBy); + + // Check if any delegations have pruning errors + const hasPruningErrors = React.useMemo(() => { + return sorted?.some(item => hasPruningError(item)); + }, [sorted]); + + // Navigate to settings page + const navigateToSettings = () => { + navigate('/settings'); + }; + + // Format error message for display + const formatErrorMessage = (message: string) => { + if (message.includes("height") && message.includes("not available")) { + return "Due to pruning strategies from validators, please navigate to the Settings tab and change your RPC node for your validator to retrieve your delegations."; + } + return message; + }; return ( - - {isLoading && } - setDelegationItemErrors(undefined)} - /> - - - - {sorted?.length - ? sorted.map((item: any) => { - if (isPendingDelegation(item)) return ; - if (isDelegation(item)) - return ( - - ); - return null; - }) - : null} - -
-
+ <> + {/* Display pruning error alert at the top if needed */} + {hasPruningErrors && ( + + Go to Settings + + } + > + Data Pruning Detected + + Some delegation details cannot be retrieved because of data pruning on the validator. + Please navigate to the Settings tab and change your RPC node to fix this issue. + + + )} + + + {isLoading && } + setDelegationItemErrors(undefined)} + /> + + + + {sorted?.length + ? sorted.map((item: any, index: number) => { + if (isPendingDelegation(item)) { + // Use index for key instead of mix_id which might not be directly accessible + return ; + } + if (isDelegation(item)) + return ( + + ); + return null; + }) + : null} + +
+
+ ); -}; +}; \ No newline at end of file