diff --git a/packages/components/src/components/Image/images.ts b/packages/components/src/components/Image/images.ts
index 5c8615037e..9390e50810 100644
--- a/packages/components/src/components/Image/images.ts
+++ b/packages/components/src/components/Image/images.ts
@@ -16,6 +16,7 @@ export const IMAGES = {
GAINS_GRAPH: 'gains-graph.svg',
GHOST: 'ghost.svg',
INVITY_LOGO: 'invity-logo.svg',
+ MORPHO_LOGO: 'morpho-logo.svg',
PLAY_STORE: 'play-store.svg',
RECOVERY_2x: 'recovery@2x.png',
STROKE_BORDER: 'stroke-border.svg',
diff --git a/packages/suite-data/files/images/images/morpho-logo.svg b/packages/suite-data/files/images/images/morpho-logo.svg
new file mode 100644
index 0000000000..1fae6f4ce2
--- /dev/null
+++ b/packages/suite-data/files/images/images/morpho-logo.svg
@@ -0,0 +1,16 @@
+
diff --git a/packages/suite/src/actions/suite/constants/suiteConstants.ts b/packages/suite/src/actions/suite/constants/suiteConstants.ts
index 3dd25b2c3f..d8bcb06306 100644
--- a/packages/suite/src/actions/suite/constants/suiteConstants.ts
+++ b/packages/suite/src/actions/suite/constants/suiteConstants.ts
@@ -16,7 +16,6 @@ export const TOR_BOOTSTRAP = '@suite/tor-bootstrap';
export const ONION_LINKS = '@suite/onion-links';
export const APP_CHANGED = '@suite/app-changed';
export const SET_THEME = '@suite/set-theme';
-export const SET_STAKING_DASHBOARD_COLLAPSED = '@suite/set-staking-dashboard-collapsed';
export const SET_SEND_FORM_PREFILL = '@suite/set-send-form-prefill';
export const SET_TRANSACTION_HISTORY_PREFILL = '@suite/set-transaction-history-prefill';
export const SET_ADDRESS_DISPLAY_TYPE = '@suite/set-display-address-type';
diff --git a/packages/suite/src/actions/suite/storageActions.ts b/packages/suite/src/actions/suite/storageActions.ts
index 3034a80da4..13ab80f288 100644
--- a/packages/suite/src/actions/suite/storageActions.ts
+++ b/packages/suite/src/actions/suite/storageActions.ts
@@ -107,7 +107,6 @@ const removeCoinjoinRelatedSetting = (state: AppState) => {
evmSettings: state.suite.evmSettings,
seenDisconnectNotificationForDeviceIds:
state.suite.seenDisconnectNotificationForDeviceIds,
- stakingDashboardCollapsed: state.suite.stakingDashboardCollapsed,
},
'suite',
true,
@@ -394,7 +393,6 @@ export const saveSuiteSettings =
evmSettings: suite.evmSettings,
seenDisconnectNotificationForDeviceIds:
suite.seenDisconnectNotificationForDeviceIds,
- stakingDashboardCollapsed: suite.stakingDashboardCollapsed,
},
'suite',
true,
diff --git a/packages/suite/src/actions/suite/suiteActions.ts b/packages/suite/src/actions/suite/suiteActions.ts
index 2a0187860a..f167f0da0f 100644
--- a/packages/suite/src/actions/suite/suiteActions.ts
+++ b/packages/suite/src/actions/suite/suiteActions.ts
@@ -81,10 +81,6 @@ export type SuiteAction =
type: typeof SUITE.SET_THEME;
variant: AppState['suite']['settings']['theme']['variant'];
}
- | {
- type: typeof SUITE.SET_STAKING_DASHBOARD_COLLAPSED;
- isCollapsed: boolean;
- }
| {
type: typeof SUITE.SET_TRANSACTION_HISTORY_PREFILL;
payload: string;
@@ -127,11 +123,6 @@ export const setTheme = (
variant,
});
-export const setStakingDashboardCollapsed = (isCollapsed: boolean): SuiteAction => ({
- type: SUITE.SET_STAKING_DASHBOARD_COLLAPSED,
- isCollapsed,
-});
-
export const setAddressDisplayType = (
option: AppState['suite']['settings']['addressDisplayType'],
): SuiteAction => ({
diff --git a/packages/suite/src/components/earn/EarnDashboard/EarnDashboard.tsx b/packages/suite/src/components/earn/EarnDashboard/EarnDashboard.tsx
new file mode 100644
index 0000000000..9a1e3b70f3
--- /dev/null
+++ b/packages/suite/src/components/earn/EarnDashboard/EarnDashboard.tsx
@@ -0,0 +1,19 @@
+import { Column } from '@trezor/components';
+
+import { useSelector } from 'src/hooks/suite';
+import { selectRouteName } from 'src/reducers/suite/routerReducer';
+
+import { EarnStakingTable } from './staking/EarnStakingTable';
+import { EarnYieldTable } from './yield/EarnYieldTable';
+
+export const EarnDashboard = () => {
+ const routeName = useSelector(selectRouteName);
+ const isOnEarnPage = routeName === 'suite-earn';
+
+ return (
+
+
+ {isOnEarnPage && }
+
+ );
+};
diff --git a/packages/suite/src/views/dashboard/StakingDashboard/StakingDashboardAccountCell.tsx b/packages/suite/src/components/earn/EarnDashboard/common/EarnAccountCell.tsx
similarity index 81%
rename from packages/suite/src/views/dashboard/StakingDashboard/StakingDashboardAccountCell.tsx
rename to packages/suite/src/components/earn/EarnDashboard/common/EarnAccountCell.tsx
index c676530f45..80881636af 100644
--- a/packages/suite/src/views/dashboard/StakingDashboard/StakingDashboardAccountCell.tsx
+++ b/packages/suite/src/components/earn/EarnDashboard/common/EarnAccountCell.tsx
@@ -4,7 +4,7 @@ import { NetworkSymbol, getNetwork } from '@suite-common/wallet-config';
import { Account } from '@suite-common/wallet-types';
import { Column } from '@trezor/components';
import { CoinLogo } from '@trezor/product-components';
-import { spacings, spacingsPx, typography } from '@trezor/theme';
+import { spacingsPx, typography } from '@trezor/theme';
import { AccountLabel, CoinBalance } from 'src/components/suite';
@@ -25,15 +25,12 @@ const AccountLabelContainer = styled.div`
white-space: nowrap;
`;
-interface StakingDashboardAccountCellProps {
+type EarnAccountCellProps = {
account?: Account;
symbol?: NetworkSymbol;
-}
+};
-export const StakingDashboardAccountCell = ({
- account,
- symbol,
-}: StakingDashboardAccountCellProps) => {
+export const EarnAccountCell = ({ account, symbol }: EarnAccountCellProps) => {
const networkSymbol = account?.symbol ?? symbol;
if (!networkSymbol) return null;
@@ -41,10 +38,10 @@ export const StakingDashboardAccountCell = ({
return (
-
+
-
+
{account ? (
;
+ children: ReactNode;
+};
+
+export const EarnDashboardSection = ({
+ titleId,
+ subheadingId,
+ provider,
+ statusBadge,
+ sectionRef,
+ children,
+}: EarnDashboardSectionProps) => {
+ const routeName = useSelector(selectRouteName);
+ const isOnEarnPage = routeName === 'suite-earn';
+ const actions = isOnEarnPage && provider ? : undefined;
+
+ return (
+
+
+ {statusBadge && (
+
+
+
+ )}
+ >
+ }
+ subheading={}
+ actions={actions}
+ ref={sectionRef}
+ >
+ {children}
+
+ );
+};
diff --git a/packages/suite/src/components/earn/EarnDashboard/common/EarnDashboardTableHeader.tsx b/packages/suite/src/components/earn/EarnDashboard/common/EarnDashboardTableHeader.tsx
new file mode 100644
index 0000000000..61e40c4006
--- /dev/null
+++ b/packages/suite/src/components/earn/EarnDashboard/common/EarnDashboardTableHeader.tsx
@@ -0,0 +1,31 @@
+import { Translation } from '@suite/intl';
+import { Table } from '@trezor/components';
+
+type EarnDashboardTableHeaderProps = {
+ showRewardsColumns?: boolean;
+};
+
+export const EarnDashboardTableHeader = ({
+ showRewardsColumns = true,
+}: EarnDashboardTableHeaderProps) => (
+
+
+
+
+
+
+
+
+
+ {showRewardsColumns && }
+
+
+ {showRewardsColumns && (
+
+ )}
+
+ {/* Actions column */}
+
+
+
+);
diff --git a/packages/suite/src/views/dashboard/StakingDashboard/StakingDashboardRewardsAmount.tsx b/packages/suite/src/components/earn/EarnDashboard/common/EarnRewardsAmount.tsx
similarity index 69%
rename from packages/suite/src/views/dashboard/StakingDashboard/StakingDashboardRewardsAmount.tsx
rename to packages/suite/src/components/earn/EarnDashboard/common/EarnRewardsAmount.tsx
index a5661032ca..e19adf30c3 100644
--- a/packages/suite/src/views/dashboard/StakingDashboard/StakingDashboardRewardsAmount.tsx
+++ b/packages/suite/src/components/earn/EarnDashboard/common/EarnRewardsAmount.tsx
@@ -3,32 +3,27 @@ import { useFormatters } from '@suite-common/formatters';
import { NetworkSymbol } from '@suite-common/wallet-config';
import { H4, TextVariant } from '@trezor/components';
-interface StakingDashboardRewardsAmountProps {
- accountSymbol: NetworkSymbol;
+type EarnRewardsAmountProps = {
+ symbol: NetworkSymbol;
rewards: string;
apy: number | null;
variant?: TextVariant;
-}
+};
-export const StakingDashboardRewardsAmount = ({
- accountSymbol,
- rewards,
- apy,
- variant,
-}: StakingDashboardRewardsAmountProps) => {
+export const EarnRewardsAmount = ({ symbol, rewards, apy, variant }: EarnRewardsAmountProps) => {
const { CryptoAmountFormatter } = useFormatters();
if (!apy)
return (
-
+
);
return (
{CryptoAmountFormatter.format(rewards, {
- symbol: accountSymbol,
+ symbol,
isBalance: true,
withSymbol: true,
isEllipsisAppended: false,
diff --git a/packages/suite/src/views/dashboard/StakingDashboard/StakingDashboardAccountRow.tsx b/packages/suite/src/components/earn/EarnDashboard/staking/EarnStakingAccountRow.tsx
similarity index 91%
rename from packages/suite/src/views/dashboard/StakingDashboard/StakingDashboardAccountRow.tsx
rename to packages/suite/src/components/earn/EarnDashboard/staking/EarnStakingAccountRow.tsx
index 2c233beea2..f6a7cfd964 100644
--- a/packages/suite/src/views/dashboard/StakingDashboard/StakingDashboardAccountRow.tsx
+++ b/packages/suite/src/components/earn/EarnDashboard/staking/EarnStakingAccountRow.tsx
@@ -28,10 +28,10 @@ import { useAnalytics } from 'src/support/useAnalytics';
import { ApyValue } from 'src/views/wallet/staking/components/ApyValue';
import { formatApyValue } from 'src/views/wallet/staking/utils/formatStakeValues';
-import { StakingDashboardAccountCell } from './StakingDashboardAccountCell';
-import { StakingDashboardRewardsAmount } from './StakingDashboardRewardsAmount';
+import { EarnAccountCell } from '../common/EarnAccountCell';
+import { EarnRewardsAmount } from '../common/EarnRewardsAmount';
-export const StakingDashboardAccountRow = ({ account }: { account: Account }) => {
+export const EarnStakingAccountRow = ({ account }: { account: Account }) => {
const dispatch = useDispatch();
const { CryptoAmountFormatter } = useFormatters();
const analytics = useAnalytics();
@@ -155,8 +155,8 @@ export const StakingDashboardAccountRow = ({ account }: { account: Account }) =>
-
@@ -164,7 +164,7 @@ export const StakingDashboardAccountRow = ({ account }: { account: Account }) =>
{isStakingActive && (
{apy && (
-
{!isCardanoNetworkType && apy && (
return (
-
+
@@ -234,7 +234,7 @@ export const StakingDashboardAccountRow = ({ account }: { account: Account }) =>
@@ -281,7 +281,7 @@ export const StakingDashboardAccountRow = ({ account }: { account: Account }) =>
-
+
@@ -305,7 +305,7 @@ export const StakingDashboardAccountRow = ({ account }: { account: Account }) =>
diff --git a/packages/suite/src/views/dashboard/StakingDashboard/StakingDashboardActivateRow.tsx b/packages/suite/src/components/earn/EarnDashboard/staking/EarnStakingActivateRow.tsx
similarity index 86%
rename from packages/suite/src/views/dashboard/StakingDashboard/StakingDashboardActivateRow.tsx
rename to packages/suite/src/components/earn/EarnDashboard/staking/EarnStakingActivateRow.tsx
index 163b413a75..c8cb53607a 100644
--- a/packages/suite/src/views/dashboard/StakingDashboard/StakingDashboardActivateRow.tsx
+++ b/packages/suite/src/components/earn/EarnDashboard/staking/EarnStakingActivateRow.tsx
@@ -8,9 +8,9 @@ import { openModal } from 'src/actions/suite/modalActions';
import { useDevice, useDispatch, useSelector } from 'src/hooks/suite';
import { ApyValue } from 'src/views/wallet/staking/components/ApyValue';
-import { StakingDashboardAccountCell } from './StakingDashboardAccountCell';
+import { EarnAccountCell } from '../common/EarnAccountCell';
-export const StakingDashboardActivateRow = ({ symbol }: { symbol: NetworkSymbol }) => {
+export const EarnStakingActivateRow = ({ symbol }: { symbol: NetworkSymbol }) => {
const dispatch = useDispatch();
const { device } = useDevice();
const apy = useSelector(state => selectPoolStatsApyData(state, undefined, symbol));
@@ -38,7 +38,7 @@ export const StakingDashboardActivateRow = ({ symbol }: { symbol: NetworkSymbol
return (
-
+
@@ -48,7 +48,7 @@ export const StakingDashboardActivateRow = ({ symbol }: { symbol: NetworkSymbol
diff --git a/packages/suite/src/views/dashboard/StakingDashboard/StakingDashboard.tsx b/packages/suite/src/components/earn/EarnDashboard/staking/EarnStakingTable.tsx
similarity index 57%
rename from packages/suite/src/views/dashboard/StakingDashboard/StakingDashboard.tsx
rename to packages/suite/src/components/earn/EarnDashboard/staking/EarnStakingTable.tsx
index 2a4647c428..4feb9a543e 100644
--- a/packages/suite/src/views/dashboard/StakingDashboard/StakingDashboard.tsx
+++ b/packages/suite/src/components/earn/EarnDashboard/staking/EarnStakingTable.tsx
@@ -1,4 +1,3 @@
-import { Translation, TranslationKey } from '@suite/intl';
import { NetworkSymbol, StakingNetworkSymbol } from '@suite-common/wallet-config';
import {
selectAccountIsStakingActive,
@@ -15,45 +14,20 @@ import {
isCardanoStakedWithFiveBinaries,
toFiatCurrency,
} from '@suite-common/wallet-utils';
-import { Badge, BadgeIntent, Card, Table } from '@trezor/components';
+import { Card, Table } from '@trezor/components';
import { BigNumber, arrayPartition } from '@trezor/utils';
-import { setStakingDashboardCollapsed } from 'src/actions/suite/suiteActions';
import { OutlineHighlight } from 'src/components/OutlineHighlight';
-import { DashboardSection } from 'src/components/dashboard';
-import { PoweredByBadge } from 'src/components/wallet';
import { DashboardAnchor } from 'src/constants/suite/anchors';
-import { useDispatch, useSelector } from 'src/hooks/suite';
+import { useSelector } from 'src/hooks/suite';
import { useAnchor } from 'src/hooks/suite/useAnchor';
import { useMessageSystemStaking } from 'src/hooks/suite/useMessageSystemStaking';
-import { selectRouteName } from 'src/reducers/suite/routerReducer';
-import { StakingDashboardAccountRow } from './StakingDashboardAccountRow';
-import { StakingDashboardActivateRow } from './StakingDashboardActivateRow';
-
-const getBadgeState = (
- isStakingActive: boolean,
- accounts: Account[],
-): { intent: BadgeIntent; label: TranslationKey } => {
- if (!isStakingActive) {
- return {
- intent: 'neutral',
- label: 'TR_STAKING_DASHBOARD_NOT_ACTIVE',
- };
- }
-
- if (accounts.some(account => isCardanoStakedWithFiveBinaries(account))) {
- return {
- intent: 'warning',
- label: 'TR_STAKING_DASHBOARD_OUTDATED',
- };
- }
-
- return {
- intent: 'brand',
- label: 'TR_STAKING_DASHBOARD_ACTIVE',
- };
-};
+import { EarnStakingAccountRow } from './EarnStakingAccountRow';
+import { EarnStakingActivateRow } from './EarnStakingActivateRow';
+import { EarnDashboardSection } from '../common/EarnDashboardSection';
+import { EarnDashboardTableHeader } from '../common/EarnDashboardTableHeader';
+import { getEarnDashboardBadgeState } from '../utils/earnDashboardBadgeUtils';
const useCryptoCurrentRate = (symbol: NetworkSymbol) => {
const baseCurrency = useSelector(selectBaseCurrency);
@@ -63,18 +37,7 @@ const useCryptoCurrentRate = (symbol: NetworkSymbol) => {
return currentRate?.rate;
};
-interface StakingDashboardProps {
- collapsible?: boolean;
-}
-
-export const StakingDashboard = ({ collapsible = true }: StakingDashboardProps) => {
- const dispatch = useDispatch();
-
- const routeName = useSelector(selectRouteName);
- const isOnEarnPage = routeName === 'suite-earn';
-
- const collapsed = useSelector(state => state.suite.stakingDashboardCollapsed);
-
+export const EarnStakingTable = () => {
const { anchorRef, shouldHighlight } = useAnchor(DashboardAnchor.Staking);
const ethCurrentRate = useCryptoCurrentRate('eth');
@@ -185,82 +148,55 @@ export const StakingDashboard = ({ collapsible = true }: StakingDashboardProps)
const ethNotActivated =
deviceSupportedNetworkSymbols.includes('eth') &&
- !stakingAccounts.find(account => account.symbol === 'eth');
+ !stakingAccounts.some(account => account.symbol === 'eth') &&
+ !isEthStakingDisabled;
const solNotActivated =
deviceSupportedNetworkSymbols.includes('sol') &&
- !stakingAccounts.find(account => account.symbol === 'sol');
+ !stakingAccounts.some(account => account.symbol === 'sol') &&
+ !isSolStakingDisabled;
const adaNotActivated =
deviceSupportedNetworkSymbols.includes('ada') &&
- !stakingAccounts.find(account => account.symbol === 'ada');
+ !stakingAccounts.some(account => account.symbol === 'ada') &&
+ !isAdaStakingDisabled;
const stakingAccountsNotActivated = ethNotActivated && solNotActivated && adaNotActivated;
- const onCollapseChange = (collapsed: boolean) => {
- if (!collapsible) return;
- dispatch(setStakingDashboardCollapsed(collapsed));
- };
-
- const badge = getBadgeState(isStakingActive, stakingAccounts);
+ const badge = getEarnDashboardBadgeState({
+ isSectionActive: isStakingActive,
+ isSectionOutdated: stakingAccounts.some(account =>
+ isCardanoStakedWithFiveBinaries(account),
+ ),
+ activeLabelId: 'TR_EARN_DASHBOARD_ACTIVE',
+ notActiveLabelId: 'TR_EARN_DASHBOARD_NOT_ACTIVE',
+ outdatedLabelId: 'TR_EARN_STAKING_DASHBOARD_OUTDATED',
+ });
return (
-
-
-
-
-
- >
- }
- subheading={}
- collapsible={collapsible}
- defaultCollapsed={collapsible ? collapsed : false}
- onCollapseChange={onCollapseChange}
- actions={isOnEarnPage ? : undefined}
- ref={anchorRef}
+
-
-
-
-
-
-
-
-
-
- {!stakingAccountsNotActivated && (
-
- )}
-
-
- {!stakingAccountsNotActivated && (
-
- )}
-
-
-
-
+
{sortedAccounts.map(account => (
-
+
))}
- {ethNotActivated && !isEthStakingDisabled && (
-
- )}
- {solNotActivated && !isSolStakingDisabled && (
-
- )}
- {adaNotActivated && !isAdaStakingDisabled && (
-
- )}
+ {ethNotActivated && }
+ {adaNotActivated && }
+ {solNotActivated && }
-
+
);
};
diff --git a/packages/suite/src/components/earn/EarnDashboard/utils/earnDashboardBadgeUtils.ts b/packages/suite/src/components/earn/EarnDashboard/utils/earnDashboardBadgeUtils.ts
new file mode 100644
index 0000000000..f213b9389f
--- /dev/null
+++ b/packages/suite/src/components/earn/EarnDashboard/utils/earnDashboardBadgeUtils.ts
@@ -0,0 +1,42 @@
+import { TranslationKey } from '@suite/intl';
+import { BadgeIntent } from '@trezor/components';
+
+type EarnDashboardBadgeState = {
+ intent: BadgeIntent;
+ labelId: TranslationKey;
+};
+
+type GetEarnDashboardBadgeStateParams = {
+ isSectionActive: boolean;
+ activeLabelId: TranslationKey;
+ notActiveLabelId: TranslationKey;
+ isSectionOutdated?: boolean;
+ outdatedLabelId?: TranslationKey;
+};
+
+export const getEarnDashboardBadgeState = ({
+ isSectionActive,
+ activeLabelId,
+ notActiveLabelId,
+ isSectionOutdated,
+ outdatedLabelId,
+}: GetEarnDashboardBadgeStateParams): EarnDashboardBadgeState => {
+ if (!isSectionActive) {
+ return {
+ intent: 'neutral',
+ labelId: notActiveLabelId,
+ };
+ }
+
+ if (isSectionOutdated && outdatedLabelId) {
+ return {
+ intent: 'warning',
+ labelId: outdatedLabelId,
+ };
+ }
+
+ return {
+ intent: 'brand',
+ labelId: activeLabelId,
+ };
+};
diff --git a/packages/suite/src/components/earn/EarnDashboard/yield/EarnYieldTable.tsx b/packages/suite/src/components/earn/EarnDashboard/yield/EarnYieldTable.tsx
new file mode 100644
index 0000000000..c0d544630d
--- /dev/null
+++ b/packages/suite/src/components/earn/EarnDashboard/yield/EarnYieldTable.tsx
@@ -0,0 +1,105 @@
+import { Translation } from '@suite/intl';
+import { selectVisibleDeviceAccounts } from '@suite-common/wallet-core';
+import { Button, Card, Paragraph, Row, Table } from '@trezor/components';
+import { BigNumber } from '@trezor/utils';
+
+import { useSelector } from 'src/hooks/suite';
+
+import { EarnAccountCell } from '../common/EarnAccountCell';
+import { EarnDashboardSection } from '../common/EarnDashboardSection';
+import { EarnDashboardTableHeader } from '../common/EarnDashboardTableHeader';
+import { getEarnDashboardBadgeState } from '../utils/earnDashboardBadgeUtils';
+
+export const EarnYieldTable = () => {
+ const visibleAccounts = useSelector(selectVisibleDeviceAccounts);
+ const ethereumAccounts = visibleAccounts.filter(account => account.symbol === 'eth');
+ const isYieldActive = ethereumAccounts.some(account =>
+ new BigNumber(account.formattedBalance).gt(0),
+ );
+
+ const badge = getEarnDashboardBadgeState({
+ isSectionActive: isYieldActive,
+ activeLabelId: 'TR_EARN_DASHBOARD_ACTIVE',
+ notActiveLabelId: 'TR_EARN_DASHBOARD_NOT_ACTIVE',
+ });
+
+ return (
+
+
+
+
+
+
+ {ethereumAccounts.length === 0 ? (
+
+
+
+
+
+
+
+ ) : (
+ ethereumAccounts.map(account => {
+ const hasBalance = new BigNumber(account.formattedBalance).gt(0);
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {hasBalance ? (
+ <>
+
+
+ >
+ ) : (
+
+ )}
+
+
+
+ );
+ })
+ )}
+
+
+
+
+ );
+};
diff --git a/packages/suite/src/components/earn/index.ts b/packages/suite/src/components/earn/index.ts
index dd36331c31..0854dee452 100644
--- a/packages/suite/src/components/earn/index.ts
+++ b/packages/suite/src/components/earn/index.ts
@@ -6,9 +6,12 @@ export { EarnProviderConsentModal } from './modals/EarnProviderConsent/EarnProvi
export { StakingEarnProviderConsentModal } from './modals/EarnProviderConsent/StakingEarnProviderConsentModal';
export { YieldEarnProviderConsentModal } from './modals/EarnProviderConsent/YieldEarnProviderConsentModal';
export { UpdateEarnProviderConsentModal } from './modals/EarnProviderConsent/UpdateEarnProviderConsentModal';
+export { EarnDashboard } from './EarnDashboard/EarnDashboard';
export { EarnSupplyingInfo } from './modals/EarnInANutshell/components/EarnSupplyingInfo';
export { EarnWithdrawingInfo } from './modals/EarnInANutshell/components/EarnWithdrawingInfo';
export { VotingDelegations } from './VotingDelegations/VotingDelegations';
export { VotingDelegationsOptions } from './VotingDelegations/VotingDelegationsOptions';
+
+export { PoweredByBadge } from './providers/PoweredByBadge';
diff --git a/packages/suite/src/components/wallet/PoweredByBadge.tsx b/packages/suite/src/components/earn/providers/PoweredByBadge.tsx
similarity index 58%
rename from packages/suite/src/components/wallet/PoweredByBadge.tsx
rename to packages/suite/src/components/earn/providers/PoweredByBadge.tsx
index 8025948a69..d892c2c2b7 100644
--- a/packages/suite/src/components/wallet/PoweredByBadge.tsx
+++ b/packages/suite/src/components/earn/providers/PoweredByBadge.tsx
@@ -1,21 +1,20 @@
import styled from 'styled-components';
import { Translation } from '@suite/intl';
-import { Image, ImageType, Row, Text } from '@trezor/components';
+import { Image, Row, Text } from '@trezor/components';
-const PROVIDERS = {
- everstake: {
- logo: 'EVERSTAKE_LOGO',
- },
-} as const satisfies Record;
+import {
+ type EarnProviderId,
+ earnProviderMetadata,
+} from 'src/components/earn/providers/providerMetadata';
const ImageWrapper = styled.div`
filter: ${({ theme }) => (theme.variant === 'dark' ? 'invert(1)' : 'none')};
`;
-interface PoweredByBadgeProps {
- provider: keyof typeof PROVIDERS;
-}
+type PoweredByBadgeProps = {
+ provider: EarnProviderId;
+};
export function PoweredByBadge({ provider }: PoweredByBadgeProps) {
return (
@@ -24,7 +23,7 @@ export function PoweredByBadge({ provider }: PoweredByBadgeProps) {
-
+
);
diff --git a/packages/suite/src/components/earn/providers/providerMetadata.ts b/packages/suite/src/components/earn/providers/providerMetadata.ts
new file mode 100644
index 0000000000..697f37b233
--- /dev/null
+++ b/packages/suite/src/components/earn/providers/providerMetadata.ts
@@ -0,0 +1,19 @@
+import { ImageType } from '@trezor/components';
+
+type ProviderMetadata = {
+ name: string;
+ logo: ImageType;
+};
+
+export const earnProviderMetadata = {
+ everstake: {
+ name: 'Everstake',
+ logo: 'EVERSTAKE_LOGO',
+ },
+ morpho: {
+ name: 'Morpho',
+ logo: 'MORPHO_LOGO',
+ },
+} as const satisfies Record;
+
+export type EarnProviderId = keyof typeof earnProviderMetadata;
diff --git a/packages/suite/src/components/wallet/index.tsx b/packages/suite/src/components/wallet/index.tsx
index 41613b5630..3221790525 100644
--- a/packages/suite/src/components/wallet/index.tsx
+++ b/packages/suite/src/components/wallet/index.tsx
@@ -3,7 +3,6 @@ import { CoinjoinAccountDiscoveryProgress } from './CoinjoinAccountDiscoveryProg
import { DiscoveryProgress } from './DiscoveryProgress';
import { InputError } from './InputError';
import { Pagination } from './Pagination';
-import { PoweredByBadge } from './PoweredByBadge';
import { TransactionTimestamp } from './TransactionTimestamp';
import { UtxoAnonymity } from './UtxoAnonymity';
import { WalletLayout } from './WalletLayout/WalletLayout';
@@ -19,5 +18,4 @@ export {
Pagination,
TransactionTimestamp,
CoinjoinAccountDiscoveryProgress,
- PoweredByBadge,
};
diff --git a/packages/suite/src/middlewares/wallet/storageMiddleware.ts b/packages/suite/src/middlewares/wallet/storageMiddleware.ts
index 4f51306cdf..2807a9e3c6 100644
--- a/packages/suite/src/middlewares/wallet/storageMiddleware.ts
+++ b/packages/suite/src/middlewares/wallet/storageMiddleware.ts
@@ -315,7 +315,6 @@ const storageMiddleware = (api: MiddlewareAPI) => {
case SUITE.SET_ADDRESS_DISPLAY_TYPE:
case SUITE.SET_AUTODETECT:
case SUITE.SET_SIDEBAR_WIDTH:
- case SUITE.SET_STAKING_DASHBOARD_COLLAPSED:
case SUITE.TOGGLE_DEVICE_AUTHENTICITY_CHECK:
case SUITE.TOGGLE_FIRMWARE_REVISION_CHECK:
case SUITE.TOGGLE_FIRMWARE_HASH_CHECK:
diff --git a/packages/suite/src/reducers/suite/suiteReducer.ts b/packages/suite/src/reducers/suite/suiteReducer.ts
index eb06f2a3b3..ee25039e6a 100644
--- a/packages/suite/src/reducers/suite/suiteReducer.ts
+++ b/packages/suite/src/reducers/suite/suiteReducer.ts
@@ -129,7 +129,6 @@ export interface SuiteState {
recentlyConnectedDeviceRef: string | null; // TODO use type DeviceRef from suite-types; currently WIP in https://github.com/trezor/trezor-suite/pull/20955
recentlyDisconnectedDevice: string | null;
seenDisconnectNotificationForDeviceIds: string[];
- stakingDashboardCollapsed: boolean;
}
const initialState: SuiteState = {
@@ -212,7 +211,6 @@ const initialState: SuiteState = {
recentlyConnectedDeviceRef: null,
recentlyDisconnectedDevice: null,
seenDisconnectNotificationForDeviceIds: [],
- stakingDashboardCollapsed: false,
};
export const suiteInitialState = initialState;
@@ -249,10 +247,6 @@ const suiteReducer = (state: SuiteState = initialState, action: Action): SuiteSt
...draft.settings,
...action.payload.suiteSettings?.settings,
};
- if (typeof action.payload.suiteSettings?.stakingDashboardCollapsed === 'boolean') {
- draft.stakingDashboardCollapsed =
- action.payload.suiteSettings.stakingDashboardCollapsed;
- }
break;
case STORAGE.ERROR:
draft.lifecycle = { status: 'db-error', error: action.payload };
@@ -327,10 +321,6 @@ const suiteReducer = (state: SuiteState = initialState, action: Action): SuiteSt
draft.settings.theme.variant = action.variant;
break;
- case SUITE.SET_STAKING_DASHBOARD_COLLAPSED:
- draft.stakingDashboardCollapsed = action.isCollapsed;
- break;
-
case SUITE.SET_SEND_FORM_PREFILL:
draft.prefillFields.sendForm = action.payload.contractAddress;
break;
diff --git a/packages/suite/src/storage/definitions.ts b/packages/suite/src/storage/definitions.ts
index 8660137932..e31842d1fe 100644
--- a/packages/suite/src/storage/definitions.ts
+++ b/packages/suite/src/storage/definitions.ts
@@ -70,7 +70,6 @@ export interface SuiteDBSchema extends DBSchema {
flags: SuiteState['flags'];
evmSettings: SuiteState['evmSettings'];
seenDisconnectNotificationForDeviceIds: SuiteState['seenDisconnectNotificationForDeviceIds'];
- stakingDashboardCollapsed: SuiteState['stakingDashboardCollapsed'];
};
};
historicRates: {
diff --git a/packages/suite/src/views/dashboard/index.tsx b/packages/suite/src/views/dashboard/index.tsx
index 2069548127..04d64dd234 100644
--- a/packages/suite/src/views/dashboard/index.tsx
+++ b/packages/suite/src/views/dashboard/index.tsx
@@ -4,6 +4,7 @@ import { Context } from '@suite-common/message-system';
import { Column } from '@trezor/components';
import { spacings, spacingsPx } from '@trezor/theme';
+import { EarnDashboard } from 'src/components/earn';
import { PageHeader } from 'src/components/suite/layouts/SuiteLayout';
import { ContextMessage } from 'src/components/wallet/WalletLayout/AccountBanners/ContextMessage';
import { useLayout } from 'src/hooks/suite';
@@ -12,7 +13,6 @@ import { AssetsView } from './AssetsView/AssetsView';
import { DashboardFooter } from './DashboardFooter';
import { DashboardPromoBanner } from './DashboardPromoBanner/DashboardPromoBanner';
import { PortfolioCard } from './PortfolioCard/PortfolioCard';
-import { StakingDashboard } from './StakingDashboard/StakingDashboard';
import { useNotificationForDisconnectedDevice } from './useNotificationForDisconnectedDevice';
const Container = styled.div`
@@ -33,7 +33,7 @@ export const Dashboard = () => {
-
+
);
diff --git a/packages/suite/src/views/earn/index.tsx b/packages/suite/src/views/earn/index.tsx
index 5ef6fd96cf..0b1038d082 100644
--- a/packages/suite/src/views/earn/index.tsx
+++ b/packages/suite/src/views/earn/index.tsx
@@ -1,10 +1,9 @@
+import { EarnDashboard } from 'src/components/earn';
import { PageHeader } from 'src/components/suite/layouts/SuiteLayout';
import { useLayout } from 'src/hooks/suite';
-import { StakingDashboard } from '../dashboard/StakingDashboard/StakingDashboard';
-
export const Earn = () => {
useLayout('Earn', );
- return ;
+ return ;
};
diff --git a/packages/suite/src/views/wallet/staking/components/StakingDashboard/components/EverstakeFooter.tsx b/packages/suite/src/views/wallet/staking/components/StakingDashboard/components/EverstakeFooter.tsx
index 58b4f6770f..bd2acbc316 100644
--- a/packages/suite/src/views/wallet/staking/components/StakingDashboard/components/EverstakeFooter.tsx
+++ b/packages/suite/src/views/wallet/staking/components/StakingDashboard/components/EverstakeFooter.tsx
@@ -9,8 +9,8 @@ import {
HELP_CENTER_SOL_STAKING,
} from '@trezor/urls';
+import { PoweredByBadge } from 'src/components/earn';
import { LearnMoreButton } from 'src/components/suite/LearnMoreButton';
-import { PoweredByBadge } from 'src/components/wallet';
import { useSelector } from 'src/hooks/suite';
import { selectSelectedAccount } from 'src/reducers/wallet/selectedAccountReducer';
diff --git a/suite/intl/src/messages.ts b/suite/intl/src/messages.ts
index 016aca90da..c1f31a8bc9 100644
--- a/suite/intl/src/messages.ts
+++ b/suite/intl/src/messages.ts
@@ -8896,25 +8896,45 @@ export const messages = defineMessages({
id: 'TR_TO',
defaultMessage: 'To',
},
- TR_STAKING_DASHBOARD_TITLE: {
- id: 'TR_STAKING_DASHBOARD_TITLE',
+ TR_EARN_STAKING_DASHBOARD_TITLE: {
+ id: 'TR_EARN_STAKING_DASHBOARD_TITLE',
defaultMessage: 'Staking',
},
- TR_STAKING_DASHBOARD_TEXT: {
- id: 'TR_STAKING_DASHBOARD_TEXT',
+ TR_EARN_STAKING_DASHBOARD_TEXT: {
+ id: 'TR_EARN_STAKING_DASHBOARD_TEXT',
defaultMessage:
'Grow your crypto by locking it to help secure the network—and earn rewards in return.',
},
- TR_STAKING_DASHBOARD_ACTIVE: {
- id: 'TR_STAKING_DASHBOARD_ACTIVE',
+ TR_EARN_YIELD_DASHBOARD_TITLE: {
+ id: 'TR_EARN_YIELD_DASHBOARD_TITLE',
+ defaultMessage: 'Stablecoin yield',
+ },
+ TR_EARN_YIELD_DASHBOARD_TEXT: {
+ id: 'TR_EARN_YIELD_DASHBOARD_TEXT',
+ defaultMessage: 'Put your stablecoins to work and earn rewards.',
+ },
+ TR_EARN_YIELD_DASHBOARD_SUPPLY_MORE: {
+ id: 'TR_EARN_YIELD_DASHBOARD_SUPPLY_MORE',
+ defaultMessage: 'Supply more',
+ },
+ TR_EARN_YIELD_DASHBOARD_WITHDRAW: {
+ id: 'TR_EARN_YIELD_DASHBOARD_WITHDRAW',
+ defaultMessage: 'Withdraw',
+ },
+ TR_EARN_YIELD_DASHBOARD_SUPPLY_NOW: {
+ id: 'TR_EARN_YIELD_DASHBOARD_SUPPLY_NOW',
+ defaultMessage: 'Supply now',
+ },
+ TR_EARN_DASHBOARD_ACTIVE: {
+ id: 'TR_EARN_DASHBOARD_ACTIVE',
defaultMessage: 'Active',
},
- TR_STAKING_DASHBOARD_NOT_ACTIVE: {
- id: 'TR_STAKING_DASHBOARD_NOT_ACTIVE',
+ TR_EARN_DASHBOARD_NOT_ACTIVE: {
+ id: 'TR_EARN_DASHBOARD_NOT_ACTIVE',
defaultMessage: 'Inactive',
},
- TR_STAKING_DASHBOARD_OUTDATED: {
- id: 'TR_STAKING_DASHBOARD_OUTDATED',
+ TR_EARN_STAKING_DASHBOARD_OUTDATED: {
+ id: 'TR_EARN_STAKING_DASHBOARD_OUTDATED',
defaultMessage: 'Outdated provider',
},
TR_STAKING_MODAL_OUTDATED: {
@@ -8930,52 +8950,52 @@ export const messages = defineMessages({
id: 'TR_STAKING_MODAL_OUTDATED_BUTTON',
defaultMessage: 'Update provider',
},
- TR_STAKING_DASHBOARD_TABLE_ACCOUNT_BALANCE: {
- id: 'TR_STAKING_DASHBOARD_TABLE_ACCOUNT_BALANCE',
- defaultMessage: 'Account',
+ TR_EARN_DASHBOARD_TABLE_ACCOUNT_BALANCE: {
+ id: 'TR_EARN_DASHBOARD_TABLE_ACCOUNT_BALANCE',
+ defaultMessage: 'Account & balance',
},
- TR_STAKING_DASHBOARD_TABLE_APY: {
- id: 'TR_STAKING_DASHBOARD_TABLE_APY',
+ TR_EARN_DASHBOARD_TABLE_APY: {
+ id: 'TR_EARN_DASHBOARD_TABLE_APY',
defaultMessage: 'APY',
},
- TR_STAKING_DASHBOARD_TABLE_YEARLY_REWARDS: {
- id: 'TR_STAKING_DASHBOARD_TABLE_YEARLY_REWARDS',
+ TR_EARN_DASHBOARD_TABLE_YEARLY_REWARDS: {
+ id: 'TR_EARN_DASHBOARD_TABLE_YEARLY_REWARDS',
defaultMessage: 'Your yearly rewards',
},
- TR_STAKING_DASHBOARD_TABLE_POTENTIAL_REWARDS: {
- id: 'TR_STAKING_DASHBOARD_TABLE_POTENTIAL_REWARDS',
+ TR_EARN_DASHBOARD_TABLE_POTENTIAL_REWARDS: {
+ id: 'TR_EARN_DASHBOARD_TABLE_POTENTIAL_REWARDS',
defaultMessage: 'Potential rewards',
},
- TR_STAKING_DASHBOARD_STAKE_NOW: {
- id: 'TR_STAKING_DASHBOARD_STAKE_NOW',
+ TR_EARN_STAKING_DASHBOARD_STAKE_NOW: {
+ id: 'TR_EARN_STAKING_DASHBOARD_STAKE_NOW',
defaultMessage: 'Stake now',
},
- TR_STAKING_DASHBOARD_STAKE_MORE: {
- id: 'TR_STAKING_DASHBOARD_STAKE_MORE',
+ TR_EARN_STAKING_DASHBOARD_STAKE_MORE: {
+ id: 'TR_EARN_STAKING_DASHBOARD_STAKE_MORE',
defaultMessage: 'Stake more',
},
- TR_STAKING_DASHBOARD_ACTIVATE: {
- id: 'TR_STAKING_DASHBOARD_ACTIVATE',
+ TR_EARN_STAKING_DASHBOARD_ACTIVATE: {
+ id: 'TR_EARN_STAKING_DASHBOARD_ACTIVATE',
defaultMessage: 'Activate {networkName}',
},
- TR_STAKING_DASHBOARD_MINIMUM_STAKE: {
- id: 'TR_STAKING_DASHBOARD_MINIMUM_STAKE',
+ TR_EARN_STAKING_DASHBOARD_MINIMUM_STAKE: {
+ id: 'TR_EARN_STAKING_DASHBOARD_MINIMUM_STAKE',
defaultMessage: 'Minimum {amount} {displaySymbol} required to stake',
},
- TR_STAKING_DASHBOARD_MAXIMUM_STAKE: {
- id: 'TR_STAKING_DASHBOARD_MAXIMUM_STAKE',
+ TR_EARN_STAKING_DASHBOARD_MAXIMUM_STAKE: {
+ id: 'TR_EARN_STAKING_DASHBOARD_MAXIMUM_STAKE',
defaultMessage: 'Maximum staked',
},
- TR_STAKING_DASHBOARD_IF_YOU_ADD: {
- id: 'TR_STAKING_DASHBOARD_IF_YOU_ADD',
+ TR_EARN_STAKING_DASHBOARD_IF_YOU_ADD: {
+ id: 'TR_EARN_STAKING_DASHBOARD_IF_YOU_ADD',
defaultMessage: 'if you add {amount} {displaySymbol}',
},
- TR_STAKING_DASHBOARD_STAKED: {
- id: 'TR_STAKING_DASHBOARD_STAKED',
+ TR_EARN_STAKING_DASHBOARD_STAKED: {
+ id: 'TR_EARN_STAKING_DASHBOARD_STAKED',
defaultMessage: '{amount} {displaySymbol} staked',
},
- TR_STAKING_DASHBOARD_OUTDATED_PROVIDER: {
- id: 'TR_STAKING_DASHBOARD_OUTDATED_PROVIDER',
+ TR_EARN_STAKING_DASHBOARD_OUTDATED_PROVIDER: {
+ id: 'TR_EARN_STAKING_DASHBOARD_OUTDATED_PROVIDER',
defaultMessage: 'Update to Everstake and earn ~{apy}% APY',
},
TR_STAKING_BANNER_DETAIL_TITLE: {
@@ -9205,8 +9225,8 @@ export const messages = defineMessages({
id: 'TR_STAKE_N_A',
defaultMessage: 'N/A',
},
- TR_STAKE_APY_REQUIRED: {
- id: 'TR_STAKE_APY_REQUIRED',
+ TR_EARN_APY_REQUIRED: {
+ id: 'TR_EARN_APY_REQUIRED',
defaultMessage: 'APY required to calculate rewards',
},
TR_STAKE_APY_DESC: {