diff --git a/packages/suite/src/support/messages.ts b/packages/suite/src/support/messages.ts
index 7d6d1326709..66ecad0c9ca 100644
--- a/packages/suite/src/support/messages.ts
+++ b/packages/suite/src/support/messages.ts
@@ -8568,6 +8568,19 @@ export default defineMessages({
defaultMessage:
'An epoch in Solana is approximately {count, plural, one {# day} other {# days}} long.',
},
+ TR_STAKE_REFRESH_REWARDS_TOOLTIP: {
+ id: 'TR_STAKE_REFRESH_REWARDS_TOOLTIP',
+ defaultMessage: 'Refresh your rewards for this account.',
+ },
+ TR_STAKE_REWARDS_ARE_EMPTY: {
+ id: 'TR_STAKE_REWARDS_ARE_EMPTY',
+ defaultMessage: 'No Rewards',
+ },
+ TR_STAKE_WAIT_TO_CHECK_REWARDS: {
+ id: 'TR_STAKE_WAIT_TO_CHECK_REWARDS',
+ defaultMessage:
+ 'Wait up to {count, plural, one {# day} other {# days}} to check your rewards',
+ },
TR_STAKE_ETH_CARD_TITLE: {
id: 'TR_STAKE_ETH_CARD_TITLE',
defaultMessage: 'The easiest way to earn {symbol}',
diff --git a/packages/suite/src/views/wallet/staking/components/SolStakingDashboard/SolStakingDashboard.tsx b/packages/suite/src/views/wallet/staking/components/SolStakingDashboard/SolStakingDashboard.tsx
index aee2796fcef..927dab19cb1 100644
--- a/packages/suite/src/views/wallet/staking/components/SolStakingDashboard/SolStakingDashboard.tsx
+++ b/packages/suite/src/views/wallet/staking/components/SolStakingDashboard/SolStakingDashboard.tsx
@@ -16,7 +16,7 @@ import { ApyCard } from '../StakingDashboard/components/ApyCard';
import { PayoutCard } from '../StakingDashboard/components/PayoutCard';
import { ClaimCard } from '../StakingDashboard/components/ClaimCard';
import { StakingCard } from '../StakingDashboard/components/StakingCard';
-import { RewardsList } from './components/RewardsList';
+import { RewardsList } from './components/Rewards/RewardsList';
interface SolStakingDashboardProps {
selectedAccount: SelectedAccountLoaded;
diff --git a/packages/suite/src/views/wallet/staking/components/SolStakingDashboard/components/Rewards/RewardsEmpty.tsx b/packages/suite/src/views/wallet/staking/components/SolStakingDashboard/components/Rewards/RewardsEmpty.tsx
new file mode 100644
index 00000000000..3956508e584
--- /dev/null
+++ b/packages/suite/src/views/wallet/staking/components/SolStakingDashboard/components/Rewards/RewardsEmpty.tsx
@@ -0,0 +1,18 @@
+import { SOLANA_EPOCH_DAYS } from '@suite-common/wallet-constants';
+
+import { Translation } from 'src/components/suite';
+import { AccountExceptionLayout } from 'src/components/wallet';
+
+export const RewardsEmpty = () => (
+ }
+ description={
+
+ }
+ iconName="arrowLineDown"
+ iconVariant="tertiary"
+ />
+);
diff --git a/packages/suite/src/views/wallet/staking/components/SolStakingDashboard/components/RewardsList.tsx b/packages/suite/src/views/wallet/staking/components/SolStakingDashboard/components/Rewards/RewardsList.tsx
similarity index 78%
rename from packages/suite/src/views/wallet/staking/components/SolStakingDashboard/components/RewardsList.tsx
rename to packages/suite/src/views/wallet/staking/components/SolStakingDashboard/components/Rewards/RewardsList.tsx
index 0112dae8154..5e1bc788e9b 100644
--- a/packages/suite/src/views/wallet/staking/components/SolStakingDashboard/components/RewardsList.tsx
+++ b/packages/suite/src/views/wallet/staking/components/SolStakingDashboard/components/Rewards/RewardsList.tsx
@@ -1,4 +1,4 @@
-import React, { useEffect, useRef, useState } from 'react';
+import React, { useCallback, useEffect, useRef, useState } from 'react';
import {
EverstakeRewardsEndpointType,
@@ -7,13 +7,24 @@ import {
StakeAccountRewards,
} from '@suite-common/wallet-core';
import { formatNetworkAmount } from '@suite-common/wallet-utils';
-import { Badge, Card, Column, Icon, Row, SkeletonStack, Text, Tooltip } from '@trezor/components';
+import {
+ Badge,
+ Card,
+ Column,
+ Icon,
+ IconButton,
+ Row,
+ SkeletonStack,
+ Text,
+ Tooltip,
+} from '@trezor/components';
import { spacings } from '@trezor/theme';
import { SOLANA_EPOCH_DAYS } from '@suite-common/wallet-constants';
+import { useDebounce } from '@trezor/react-utils';
import {
- CoinBalance,
FiatValue,
+ FormattedCryptoAmount,
FormattedDate,
HiddenPlaceholder,
Translation,
@@ -25,6 +36,8 @@ import { Pagination } from 'src/components/wallet';
import SkeletonTransactionItem from 'src/views/wallet/transactions/TransactionList/SkeletonTransactionItem';
import { ColDate } from 'src/views/wallet/transactions/TransactionList/TransactionsGroup/CommonComponents';
+import { RewardsEmpty } from './RewardsEmpty';
+
const PAGE_SIZE_DEFAULT = 10;
interface RewardsListProps {
@@ -32,14 +45,16 @@ interface RewardsListProps {
}
export const RewardsList = ({ account }: RewardsListProps) => {
- const anchor = useSelector(state => state.router.anchor);
const { data, isLoading } =
- useSelector(state => selectStakingRewards(state, account?.symbol)) || {};
+ useSelector(state => selectStakingRewards(state, account.symbol)) || {};
const { rewards } = data ?? {};
+ const selectedAccountRewards = rewards?.[account.descriptor];
+
const sectionRef = useRef(null);
const dispatch = useDispatch();
+ const debounce = useDebounce();
const perPage = PAGE_SIZE_DEFAULT;
const startPage = 1;
@@ -50,32 +65,41 @@ export const RewardsList = ({ account }: RewardsListProps) => {
const startIndex = (currentPage - 1) * perPage;
const stopIndex = startIndex + perPage;
+ const isSolanaMainnet = account.symbol === 'sol';
+
+ const fetchRewards = useCallback(
+ async ({ symbol, descriptor }: Account) => {
+ await debounce(() => {
+ if (symbol !== 'sol') return;
+ dispatch(
+ fetchEverstakeRewards({
+ symbol,
+ endpointType: EverstakeRewardsEndpointType.GetRewards,
+ address: descriptor,
+ }),
+ );
+ });
+ },
+ [dispatch, debounce],
+ );
+
useEffect(() => {
- // Fetch rewards only for the Solana mainnet
- if (account.symbol === 'sol') {
- dispatch(
- fetchEverstakeRewards({
- symbol: account.symbol,
- endpointType: EverstakeRewardsEndpointType.GetRewards,
- address: account.descriptor,
- }),
- );
- }
- }, [anchor, account, dispatch]);
+ fetchRewards(account);
+ }, [account, fetchRewards]);
useEffect(() => {
- if (rewards) {
- const slicedRewards = rewards?.slice(startIndex, stopIndex);
+ if (selectedAccountRewards) {
+ const slicedRewards = selectedAccountRewards?.slice(startIndex, stopIndex);
setSlicedRewards(slicedRewards);
}
- }, [currentPage, rewards, startIndex, stopIndex]);
+ }, [currentPage, selectedAccountRewards, startIndex, stopIndex]);
useEffect(() => {
// reset page on account change
setSelectedPage(startPage);
}, [account.descriptor, account.symbol, startPage]);
- const totalItems = rewards?.length ?? 0;
+ const totalItems = selectedAccountRewards?.length ?? 0;
const showPagination = totalItems > perPage;
const isLastPage = stopIndex >= totalItems;
@@ -86,10 +110,29 @@ export const RewardsList = ({ account }: RewardsListProps) => {
}
};
+ if (!isSolanaMainnet || !totalItems) {
+ return ;
+ }
+
return (
}
+ actions={
+
+ }
+ >
+ fetchRewards(account)}
+ />
+
+
+ }
data-testid="@wallet/accounts/rewards-list"
>
{isLoading ? (
@@ -147,7 +190,7 @@ export const RewardsList = ({ account }: RewardsListProps) => {
{reward?.amount && (
- {
const { symbol } = action.meta.arg;
- if (!state.data[symbol]) {
+ if (!state.data[symbol]?.stakingRewards) {
state.data[symbol] = {
stakingRewards: {
error: false,
diff --git a/suite-common/wallet-core/src/stake/stakeThunks.ts b/suite-common/wallet-core/src/stake/stakeThunks.ts
index 3c6b34d5045..6ff9a4778a9 100644
--- a/suite-common/wallet-core/src/stake/stakeThunks.ts
+++ b/suite-common/wallet-core/src/stake/stakeThunks.ts
@@ -19,7 +19,7 @@ import {
EverstakeEndpointType,
EverstakeRewardsEndpointType,
ValidatorsQueue,
- StakeAccountRewards,
+ StakeRewardsByAccount,
} from './stakeTypes';
import { EVERSTAKE_ENDPOINT_PREFIX, EVERSTAKE_REWARDS_SOLANA_ENPOINT } from './stakeConstants';
import { selectAllNetworkSymbolsOfVisibleAccounts } from '../accounts/accountsReducer';
@@ -108,7 +108,7 @@ export const fetchEverstakeAssetData = createThunk<
);
export const fetchEverstakeRewards = createThunk<
- { rewards: StakeAccountRewards[] },
+ { rewards: StakeRewardsByAccount },
{
symbol: SupportedSolanaNetworkSymbols;
endpointType: EverstakeRewardsEndpointType;
@@ -132,7 +132,9 @@ export const fetchEverstakeRewards = createThunk<
const data = await response.json();
return fulfillWithValue({
- rewards: data,
+ rewards: {
+ [address]: data,
+ },
});
} catch (error) {
return rejectWithValue(error.toString());
diff --git a/suite-common/wallet-core/src/stake/stakeTypes.ts b/suite-common/wallet-core/src/stake/stakeTypes.ts
index 275f78da9c5..7099869d0df 100644
--- a/suite-common/wallet-core/src/stake/stakeTypes.ts
+++ b/suite-common/wallet-core/src/stake/stakeTypes.ts
@@ -105,3 +105,7 @@ export type StakeAccountRewards = {
currency: string;
time: string;
};
+
+export type StakeRewardsByAccount = {
+ [address: string]: StakeAccountRewards[];
+};