diff --git a/.changeset/fresh-dragons-smile.md b/.changeset/fresh-dragons-smile.md
new file mode 100644
index 000000000000..5e12dc401fb7
--- /dev/null
+++ b/.changeset/fresh-dragons-smile.md
@@ -0,0 +1,5 @@
+---
+"live-mobile": patch
+---
+
+Re-use account-specific stake flow actions directly in the Earn Navigator to avoid empty stake flow navigation that was causing empty modals to appear.
diff --git a/apps/ledger-live-mobile/src/components/RootNavigator/BaseNavigator.tsx b/apps/ledger-live-mobile/src/components/RootNavigator/BaseNavigator.tsx
index 722ca1f5a597..dfb0b3564ebd 100644
--- a/apps/ledger-live-mobile/src/components/RootNavigator/BaseNavigator.tsx
+++ b/apps/ledger-live-mobile/src/components/RootNavigator/BaseNavigator.tsx
@@ -289,11 +289,6 @@ export default function BaseNavigator() {
options={{ headerShown: false }}
{...noNanoBuyNanoWallScreenOptions}
/>
-
+
();
@@ -29,6 +30,12 @@ const Earn = (props: NavigationProps) => {
const accounts = useSelector(accountsSelector);
const route = useRoute();
+ const openStakingDrawer = useStakingDrawer({
+ navigation,
+ parentRoute: route,
+ alwaysShowNoFunds: false,
+ });
+
useEffect(() => {
if (!ptxEarn?.enabled) {
return navigation.pop();
@@ -63,13 +70,7 @@ const Earn = (props: NavigationProps) => {
const accountId = getAccountIdFromWalletAccountId(walletId);
const account = accounts.find(acc => acc.id === accountId);
if (account) {
- navigation.navigate(NavigatorName.StakeFlow, {
- screen: ScreenName.Stake,
- params: {
- account,
- parentRoute: route,
- },
- });
+ openStakingDrawer(account);
} else {
// eslint-disable-next-line no-console
console.log("no matching account found for given id.");
@@ -88,7 +89,7 @@ const Earn = (props: NavigationProps) => {
params: {
currencies: [currencyId],
parentRoute: route,
- // Stake flow will get CryptoCurrency and Account, and navigate to NoFunds flow:
+ // Stake flow will skip step 1 (select CryptoCurrency) and step 2 (select Account), and navigate straight to NoFunds flow:
alwaysShowNoFunds: true, // Navigate to NoFunds even if some funds available.
},
});
@@ -105,7 +106,15 @@ const Earn = (props: NavigationProps) => {
deeplinkRouting();
return clearDeepLink();
- }, [paramAction, ptxEarn?.enabled, props.route.params, accounts, navigation, route]);
+ }, [
+ paramAction,
+ ptxEarn?.enabled,
+ props.route.params,
+ accounts,
+ navigation,
+ route,
+ openStakingDrawer,
+ ]);
return (
<>
diff --git a/apps/ledger-live-mobile/src/components/Stake/index.tsx b/apps/ledger-live-mobile/src/components/Stake/index.tsx
index 93a4872b1398..eeb2d25b44e4 100644
--- a/apps/ledger-live-mobile/src/components/Stake/index.tsx
+++ b/apps/ledger-live-mobile/src/components/Stake/index.tsx
@@ -2,14 +2,14 @@
import { useMemo, useLayoutEffect, useCallback } from "react";
import { StackNavigationProp } from "@react-navigation/stack";
import { useNavigation } from "@react-navigation/native";
-import { Account } from "@ledgerhq/types-live";
import { listCurrencies, filterCurrencies } from "@ledgerhq/live-common/currencies/helpers";
import { useFeature } from "@ledgerhq/live-common/featureFlags/index";
import { NavigatorName, ScreenName } from "../../const";
-import perFamilyAccountActions from "../../generated/accountActions";
import type { StackNavigatorProps, BaseComposite } from "../RootNavigator/types/helpers";
import type { StakeNavigatorParamList } from "../RootNavigator/types/StakeNavigator";
+import { useStakingDrawer } from "./useStakingDrawer";
+
type Props = BaseComposite>;
const StakeFlow = ({ route }: Props) => {
@@ -26,57 +26,7 @@ const StakeFlow = ({ route }: Props) => {
});
}, [currencies]);
- const goToAccount = useCallback(
- (account: Account, parentAccount?: Account) => {
- if (alwaysShowNoFunds) {
- navigation.navigate(NavigatorName.Base, {
- screen: NavigatorName.NoFundsFlow,
- drawer: undefined,
- params: {
- screen: ScreenName.NoFunds,
- params: {
- account,
- parentAccount,
- },
- },
- });
- return;
- }
-
- // @ts-expect-error issue in typing
- const decorators = perFamilyAccountActions[account?.currency?.family];
- const familySpecificMainActions =
- (decorators &&
- decorators.getMainActions &&
- decorators.getMainActions({
- account,
- parentAccount,
- colors: {},
- parentRoute,
- })) ||
- [];
- const stakeFlow = familySpecificMainActions.find(
- (action: { id: string }) => action.id === "stake",
- )?.navigationParams;
- if (!stakeFlow) return null;
-
- const [name, options] = stakeFlow;
-
- navigation.navigate(NavigatorName.Base, {
- screen: name,
- drawer: options?.drawer,
- params: {
- screen: options.screen,
- params: {
- ...(options?.params || {}),
- account,
- parentAccount,
- },
- },
- });
- },
- [navigation, parentRoute, alwaysShowNoFunds],
- );
+ const goToAccountStakeFlow = useStakingDrawer({ navigation, parentRoute, alwaysShowNoFunds });
const requestAccount = useCallback(() => {
if (cryptoCurrencies.length === 1) {
@@ -85,7 +35,7 @@ const StakeFlow = ({ route }: Props) => {
screen: ScreenName.RequestAccountsSelectAccount,
params: {
currency: cryptoCurrencies[0],
- onSuccess: goToAccount,
+ onSuccess: goToAccountStakeFlow,
allowAddAccount: true, // if no account, need to be able to add one to get funds.
},
});
@@ -95,19 +45,19 @@ const StakeFlow = ({ route }: Props) => {
params: {
currencies: cryptoCurrencies,
allowAddAccount: true,
- onSuccess: goToAccount,
+ onSuccess: goToAccountStakeFlow,
},
});
}
- }, [cryptoCurrencies, navigation, goToAccount]);
+ }, [cryptoCurrencies, navigation, goToAccountStakeFlow]);
useLayoutEffect(() => {
if (account) {
- goToAccount(account);
+ goToAccountStakeFlow(account);
} else {
requestAccount();
}
- }, [requestAccount, goToAccount, account]);
+ }, [requestAccount, goToAccountStakeFlow, account]);
return null;
};
diff --git a/apps/ledger-live-mobile/src/components/Stake/useStakingDrawer.tsx b/apps/ledger-live-mobile/src/components/Stake/useStakingDrawer.tsx
new file mode 100644
index 000000000000..1527da2da36c
--- /dev/null
+++ b/apps/ledger-live-mobile/src/components/Stake/useStakingDrawer.tsx
@@ -0,0 +1,68 @@
+import { StackNavigationProp } from "@react-navigation/stack";
+import { ParamListBase, RouteProp } from "@react-navigation/native";
+import { Account } from "@ledgerhq/types-live";
+import { NavigatorName, ScreenName } from "../../const";
+import perFamilyAccountActions from "../../generated/accountActions";
+
+/** Open the stake flow for a given account from any navigator. Returns to parent route on completion. */
+export function useStakingDrawer({
+ navigation,
+ parentRoute,
+ alwaysShowNoFunds,
+}: {
+ navigation: StackNavigationProp<{ [key: string]: object | undefined }>;
+ parentRoute: RouteProp | undefined;
+ alwaysShowNoFunds?: boolean | undefined;
+}) {
+ return (account: Account, parentAccount?: Account) => {
+ if (alwaysShowNoFunds) {
+ // get funds to stake with
+ navigation.navigate(NavigatorName.Base, {
+ screen: NavigatorName.NoFundsFlow,
+ drawer: undefined,
+ params: {
+ screen: ScreenName.NoFunds,
+ params: {
+ account,
+ parentAccount,
+ },
+ },
+ });
+ return;
+ }
+
+ // @ts-expect-error issue in typing
+ const decorators = perFamilyAccountActions[account?.currency?.family];
+ // get the stake flow for the specific currency
+ const familySpecificMainActions =
+ (decorators &&
+ decorators.getMainActions &&
+ decorators.getMainActions({
+ account,
+ parentAccount,
+ colors: {},
+ parentRoute,
+ })) ||
+ [];
+ const stakeFlow = familySpecificMainActions.find(
+ (action: { id: string }) => action.id === "stake",
+ )?.navigationParams;
+ if (!stakeFlow) return null;
+
+ const [name, options] = stakeFlow;
+
+ // open staking drawer (or stake flow screens) for the specific currency, inside the current navigator
+ navigation.navigate(NavigatorName.Base, {
+ screen: name,
+ drawer: options?.drawer,
+ params: {
+ screen: options.screen,
+ params: {
+ ...(options?.params || {}),
+ account,
+ parentAccount,
+ },
+ },
+ });
+ };
+}
diff --git a/apps/ledger-live-mobile/src/components/TabBar/TransferDrawer.tsx b/apps/ledger-live-mobile/src/components/TabBar/TransferDrawer.tsx
index 2ed5a3a02a79..105ae7e2a260 100644
--- a/apps/ledger-live-mobile/src/components/TabBar/TransferDrawer.tsx
+++ b/apps/ledger-live-mobile/src/components/TabBar/TransferDrawer.tsx
@@ -111,10 +111,12 @@ export default function TransferDrawer({ onClose }: Omit onNavigate(NavigatorName.Exchange, { screen: ScreenName.ExchangeBuy }),
[onNavigate],
);
+
const onSell = useCallback(
() => onNavigate(NavigatorName.Exchange, { screen: ScreenName.ExchangeSell }),
[onNavigate],