Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: add account v2 redirection from receive when no account found / add account v1 is OK #8999

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/new-bulldogs-hope.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"live-mobile": minor
---

Fix redirection to add account v2 when the user try to receive on 0 accounts based currency
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import {
} from "@ledgerhq/types-cryptoassets";
import { Device, DeviceModelId } from "@ledgerhq/types-devices";
import { AccountLike } from "@ledgerhq/types-live";
import type { ScreenName } from "~/const";
import { NavigatorScreenParams } from "@react-navigation/native";
import type { NavigatorName, ScreenName } from "~/const";
import { DeviceSelectionNavigatorParamsList } from "LLM/features/DeviceSelection/types";

export type ReceiveFundsStackParamList = {
[ScreenName.ReceiveSelectCrypto]:
Expand Down Expand Up @@ -76,4 +78,7 @@ export type ReceiveFundsStackParamList = {
onSuccess?: (_?: string) => void;
onError?: () => void;
};
[NavigatorName.DeviceSelection]?: Partial<
NavigatorScreenParams<DeviceSelectionNavigatorParamsList>
>;
};
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { LoadingBasedGroupedCurrencies, LoadingStatus } from "@ledgerhq/live-com
import { CryptoCurrency, TokenCurrency } from "@ledgerhq/types-cryptoassets";
import { TrackingEvent } from "../../enums";
import { parseBoolean } from "LLM/utils/parseBoolean";
import { AddAccountContexts } from "../AddAccount/enums";
type Props = StackNavigatorProps<AccountsListNavigator, ScreenName.AccountsList>;

export default function AccountsList({ route }: Props) {
Expand Down Expand Up @@ -85,15 +86,15 @@ export default function AccountsList({ route }: Props) {
screen: ScreenName.SelectNetwork,
params: {
currency: currency.id,
context: "addAccounts",
context: AddAccountContexts.AddAccounts,
},
});
} else {
navigation.navigate(NavigatorName.DeviceSelection, {
screen: ScreenName.SelectDevice,
params: {
currency: currency as CryptoCurrency,
context: "addAccounts",
context: AddAccountContexts.AddAccounts,
},
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { useCallback, useMemo } from "react";
import { track } from "~/analytics";
import { useFeature } from "@ledgerhq/live-common/featureFlags/index";
import { CryptoCurrency, TokenCurrency } from "@ledgerhq/types-cryptoassets";
import { AddAccountContexts } from "../../enums";

type AddAccountScreenProps = {
currency?: CryptoCurrency | TokenCurrency | null;
Expand All @@ -31,16 +32,22 @@ const useSelectAddAccountMethodViewModel = ({
if (currency?.type === "TokenCurrency") {
return {
token: currency,
...(llmNetworkBasedAddAccountFlow?.enabled && { context: "addAccounts" }),
...(llmNetworkBasedAddAccountFlow?.enabled && {
context: AddAccountContexts.AddAccounts,
}),
};
} else {
return {
currency,
...(llmNetworkBasedAddAccountFlow?.enabled && { context: "addAccounts" }),
...(llmNetworkBasedAddAccountFlow?.enabled && {
context: AddAccountContexts.AddAccounts,
}),
};
}
} else {
return llmNetworkBasedAddAccountFlow?.enabled ? { context: "addAccounts" } : {};
return llmNetworkBasedAddAccountFlow?.enabled
? { context: AddAccountContexts.AddAccounts }
: {};
}
}, [hasCurrency, currency, llmNetworkBasedAddAccountFlow?.enabled]);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export enum AddAccountContexts {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i like enums , newer versions of typescripts support it very well in term of typing/inference(in the ends they are objects), in term of system design there is a huge difference between an enumeration and an Object to define limited set of values for a type. It's readable. There will be no issues in transpilation/ build / performance time. Why don't we ?

AddAccounts = "addAccounts",
ReceiveFunds = "receiveFunds",
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ import { ScreenName } from "~/const";
import { Device } from "@ledgerhq/types-devices";
import { Account } from "@ledgerhq/types-live";
import { Props as TouchableProps } from "~/components/Touchable";
import { AddAccountContexts } from "./enums";

export type AddAccountContextType = `${AddAccountContexts}`;

type CommonParams = {
context?: "addAccounts" | "receiveFunds";
context?: AddAccountContextType;
onSuccess?: () => void;
onCloseNavigation?: () => void;
currency: CryptoOrTokenCurrency;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
View,
} from "react-native";
import { useTheme } from "styled-components/native";
import { ScreenName } from "~/const";
import { NavigatorName, ScreenName } from "~/const";
import { TrackScreen } from "~/analytics";
import type { BaseComposite, StackNavigatorProps } from "~/components/RootNavigator/types/helpers";
import AccountItem from "../../components/AccountsListView/components/AccountItem";
Expand All @@ -26,6 +26,7 @@ import { useNavigation } from "@react-navigation/core";
import useAnimatedStyle from "../ScanDeviceAccounts/components/ScanDeviceAccountsFooter/useAnimatedStyle";
import AddFundsButton from "../../components/AddFundsButton";
import CloseWithConfirmation from "LLM/components/CloseWithConfirmation";
import { AddAccountContexts } from "../AddAccount/enums";

type Props = BaseComposite<
StackNavigatorProps<NetworkBasedAddAccountNavigator, ScreenName.AddAccountsSuccess>
Expand All @@ -37,18 +38,26 @@ export default function AddAccountsSuccess({ route }: Props) {
const insets = useSafeAreaInsets();
const navigation = useNavigation();
const { animatedSelectableAccount } = useAnimatedStyle();
const { currency, accountsToAdd, onCloseNavigation, context } = route.params || {};

const goToAccounts = useCallback(
(accountId: string) => () => {
navigation.navigate(ScreenName.Account, {
accountId,
});
if (context === AddAccountContexts.AddAccounts)
navigation.navigate(ScreenName.Account, {
accountId,
});
else
navigation.navigate(NavigatorName.ReceiveFunds, {
screen: ScreenName.ReceiveConfirmation,
params: {
...route.params,
accountId,
},
});
},
[navigation],
[navigation, route.params, context],
);

const { currency, accountsToAdd, onCloseNavigation } = route.params || {};

const renderItem = useCallback(
({ item }: ListRenderItemInfo<AccountLikeEnhanced>) => (
<Animated.View style={[animatedSelectableAccount]}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Flex, Icons, rgba, Text } from "@ledgerhq/native-ui";
import { useTranslation } from "react-i18next";
import { Animated, StyleSheet, TouchableOpacity, View } from "react-native";
import { useTheme } from "styled-components/native";
import { ScreenName } from "~/const";
import { NavigatorName, ScreenName } from "~/const";
import type { BaseComposite, StackNavigatorProps } from "~/components/RootNavigator/types/helpers";
import AccountItem from "../../components/AccountsListView/components/AccountItem";
import { Account } from "@ledgerhq/types-live";
Expand All @@ -17,6 +17,7 @@ import { useNavigation } from "@react-navigation/core";
import useAnimatedStyle from "../ScanDeviceAccounts/components/ScanDeviceAccountsFooter/useAnimatedStyle";
import AddFundsButton from "../../components/AddFundsButton";
import CloseWithConfirmation from "LLM/components/CloseWithConfirmation";
import { AddAccountContexts } from "../AddAccount/enums";
type Props = BaseComposite<
StackNavigatorProps<NetworkBasedAddAccountNavigator, ScreenName.AddAccountsWarning>
>;
Expand All @@ -29,17 +30,28 @@ export default function AddAccountsWarning({ route }: Props) {

const { animatedSelectableAccount } = useAnimatedStyle();

const { emptyAccount, emptyAccountName, currency, context } = route.params || {};

const statusColor = colors.warning.c70;

const goToAccounts = useCallback(
(accountId: string) => () => {
navigation.navigate(ScreenName.Account, {
accountId,
});
if (context === AddAccountContexts.AddAccounts) {
navigation.navigate(ScreenName.Account, {
accountId,
});
} else {
navigation.navigate(NavigatorName.ReceiveFunds, {
screen: ScreenName.ReceiveConfirmation,
params: {
...route.params,
accountId,
},
});
}
},
[navigation],
[navigation, route.params, context],
);
const { emptyAccount, emptyAccountName, currency } = route.params || {};

const statusColor = colors.warning.c70;

const handleOnCloseWarningScreen = useCallback(() => {
navigation.goBack();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
mockGroupedCurrenciesBySingleProviderData,
mockGroupedCurrenciesWithMultipleProviderData,
} from "./mockData";
import { AddAccountContexts } from "../../Accounts/screens/AddAccount/enums";

const MockUseRoute = useRoute as jest.Mock;
const MockUseGroupedCurrenciesByProvider = useGroupedCurrenciesByProvider as jest.Mock;
Expand Down Expand Up @@ -39,7 +40,7 @@ describe("Asset Selection test suite", () => {
it("should render crypto selection screen when no currency is defined in the navigation route showing a loader", () => {
MockUseRoute.mockReturnValue({
params: {
context: "addAccounts",
context: AddAccountContexts.AddAccounts,
},
});

Expand All @@ -62,7 +63,7 @@ describe("Asset Selection test suite", () => {
it("should render crypto selection screen with empty list when useGroupedCurrenciesByProvider finish loading with empty result", () => {
MockUseRoute.mockReturnValue({
params: {
context: "addAccounts",
context: AddAccountContexts.AddAccounts,
},
});

Expand All @@ -79,7 +80,7 @@ describe("Asset Selection test suite", () => {
it("should display a list of cryptocurrencies when useGroupedCurrenciesByProvider successfully loads data", () => {
MockUseRoute.mockReturnValue({
params: {
context: "addAccounts",
context: AddAccountContexts.AddAccounts,
},
});

Expand All @@ -98,7 +99,7 @@ describe("Asset Selection test suite", () => {
it("should navigate to network selection when currency has more than one network provider", () => {
MockUseRoute.mockReturnValue({
params: {
context: "addAccounts",
context: AddAccountContexts.AddAccounts,
currency: "ethereum",
},
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import type { CryptoCurrency, TokenCurrency } from "@ledgerhq/types-cryptoassets
import { AssetSelectionNavigationProps, CommonParams } from "../../types";
import { useGroupedCurrenciesByProvider } from "@ledgerhq/live-common/deposit/index";
import { LoadingBasedGroupedCurrencies } from "@ledgerhq/live-common/deposit/type";
import { AddAccountContexts } from "LLM/features/Accounts/screens/AddAccount/enums";

type SelectCryptoViewModelProps = Pick<CommonParams, "context"> & {
filterCurrencyIds?: string[];
Expand Down Expand Up @@ -58,15 +59,15 @@ export default function useSelectCryptoViewModel({
navigation.navigate(ScreenName.SelectNetwork, {
context,
currency: curr.id,
...(context === "receiveFunds" && { filterCurrencyIds }),
...(context === AddAccountContexts.AddAccounts && { filterCurrencyIds }),
});
return;
}

const isToken = curr.type === "TokenCurrency";
const currency = isToken ? curr.parentCurrency : curr;
const currencyAccounts = findAccountByCurrency(accounts, currency);
const isAddAccountContext = context === "addAccounts";
const isAddAccountContext = context === AddAccountContexts.AddAccounts;

if (currencyAccounts.length > 0 && !isAddAccountContext) {
// If we found one or more accounts of the currency then we select account
Expand Down Expand Up @@ -113,12 +114,12 @@ export default function useSelectCryptoViewModel({
);
const { titleText, titleTestId } = useMemo(() => {
switch (context) {
case "addAccounts":
case AddAccountContexts.AddAccounts:
return {
titleText: t("assetSelection.selectCrypto.title"),
titleTestId: "select-crypto-header-step1-title",
};
case "receiveFunds":
case AddAccountContexts.ReceiveFunds:
return {
titleText: t("transfer.receive.selectCrypto.title"),
titleTestId: "receive-header-step1-title",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { AssetSelectionNavigationProps, SelectNetworkRouteParams } from "../../t
import { CryptoWithAccounts } from "./types";
import { LoadingBasedGroupedCurrencies } from "@ledgerhq/live-common/deposit/type";
import { useGroupedCurrenciesByProvider } from "@ledgerhq/live-common/deposit/index";
import { AddAccountContexts } from "LLM/features/Accounts/screens/AddAccount/enums";

export default function useSelectNetworkViewModel({
filterCurrencyIds,
Expand Down Expand Up @@ -124,7 +125,7 @@ export default function useSelectNetworkViewModel({
);

if (!cryptoToSend) return;
const isAddAccountContext = context === "addAccounts";
const isAddAccountContext = context === AddAccountContexts.AddAccounts;

const accs = findAccountByCurrency(accounts, cryptoToSend);

Expand Down Expand Up @@ -191,15 +192,15 @@ export default function useSelectNetworkViewModel({
string
> => {
switch (context) {
case "receiveFunds":
case AddAccountContexts.ReceiveFunds:
return {
titleText: t("selectNetwork.swap.title"),
titleTestId: "receive-header-step2-title",
subtitleText: t("selectNetwork.swap.subtitle"),
subTitleTestId: "transfer.receive.selectNetwork.subtitle",
listTestId: "receive-header-step2-networks",
};
case "addAccounts":
case AddAccountContexts.AddAccounts:
return {
titleText: t("assetSelection.selectNetwork.title"),
titleTestId: "addAccounts-header-step2-title",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { NavigatorScreenParams } from "@react-navigation/core";
import { NavigatorName, ScreenName } from "~/const";
import { DeviceSelectionNavigatorParamsList } from "../DeviceSelection/types";
import { NetworkBasedAddAccountNavigator } from "../Accounts/screens/AddAccount/types";
import {
AddAccountContextType,
NetworkBasedAddAccountNavigator,
} from "../Accounts/screens/AddAccount/types";
import { StackNavigatorProps } from "~/components/RootNavigator/types/helpers";
export type CommonParams = {
context?: "addAccounts" | "receiveFunds";
context?: AddAccountContextType;
onSuccess?: () => void;
currency?: string;
inline?: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useRoute, useNavigation } from "@react-navigation/native";
import { discoverDevices } from "@ledgerhq/live-common/hw/index";
import { DeviceModelId } from "@ledgerhq/types-devices";
import { of } from "rxjs";
import { AddAccountContexts } from "../../Accounts/screens/AddAccount/enums";

const MockUseRoute = useRoute as jest.Mock;
const mockNavigate = jest.fn();
Expand Down Expand Up @@ -34,7 +35,7 @@ describe("Device Selection feature integration test", () => {
beforeAll(() => {
MockUseRoute.mockReturnValue({
params: {
context: "addAccounts",
context: AddAccountContexts.AddAccounts,
currency: {
type: "CryptoCurrency",
id: "bitcoin",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { CryptoCurrency } from "@ledgerhq/types-cryptoassets";
import { NavigatorScreenParams } from "@react-navigation/core";
import { NavigatorName, ScreenName } from "~/const";
import { NetworkBasedAddAccountNavigator } from "../Accounts/screens/AddAccount/types";
import {
AddAccountContextType,
NetworkBasedAddAccountNavigator,
} from "../Accounts/screens/AddAccount/types";
import { StackNavigatorProps } from "~/components/RootNavigator/types/helpers";

type CommonParams = {
context?: "addAccounts" | "receiveFunds";
context?: AddAccountContextType;
onSuccess?: () => void;
onCloseNavigation?: () => void;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import QueuedDrawer from "~/components/QueuedDrawer";
import type { BaseComposite, StackNavigatorProps } from "~/components/RootNavigator/types/helpers";
import { MyLedgerNavigatorStackParamList } from "~/components/RootNavigator/types/MyLedgerNavigator";
import { useFeature } from "@ledgerhq/live-common/featureFlags/index";
import { AddAccountContexts } from "~/newArch/features/Accounts/screens/AddAccount/enums";

type NavigationProps = BaseComposite<
StackNavigatorProps<MyLedgerNavigatorStackParamList, ScreenName.MyLedgerDevice>
Expand Down Expand Up @@ -54,7 +55,7 @@ const InstallSuccessBar = ({ state, navigation, disable }: Props) => {
const onAddAccount = useCallback(() => {
if (llmNetworkBasedAddAccountFlow?.enabled)
navigation.navigate(NavigatorName.AssetSelection, {
context: "addAccounts",
context: AddAccountContexts.AddAccounts,
});
else navigation.navigate(NavigatorName.AddAccounts);

Expand Down
Loading
Loading