diff --git a/mobile-app/app/components/AddressEvmTag.tsx b/mobile-app/app/components/AddressEvmTag.tsx
new file mode 100644
index 0000000000..cc7a0af821
--- /dev/null
+++ b/mobile-app/app/components/AddressEvmTag.tsx
@@ -0,0 +1,27 @@
+import { tailwind } from "@tailwind";
+import { LinearGradient } from "expo-linear-gradient";
+
+export function AddressEvmTag({
+ children,
+ customStyle,
+ testID,
+}: {
+ children: React.ReactElement;
+ customStyle?: string;
+ testID: string;
+}): JSX.Element {
+ return (
+
+ {children}
+
+ );
+}
diff --git a/mobile-app/app/components/EvmTag.tsx b/mobile-app/app/components/EvmTag.tsx
new file mode 100644
index 0000000000..091ccfb555
--- /dev/null
+++ b/mobile-app/app/components/EvmTag.tsx
@@ -0,0 +1,31 @@
+import { tailwind } from "@tailwind";
+import { Text } from "@components/Text";
+import { LinearGradient } from "expo-linear-gradient";
+
+export function EvmTag({
+ text = "EVM",
+ index,
+ testIDSuffix,
+}: {
+ text?: string;
+ index: number;
+ testIDSuffix: string;
+}): JSX.Element {
+ return (
+
+
+ {text}
+
+
+ );
+}
diff --git a/mobile-app/app/components/SummaryTitle.tsx b/mobile-app/app/components/SummaryTitle.tsx
index c21ad98cd2..527f7cf021 100644
--- a/mobile-app/app/components/SummaryTitle.tsx
+++ b/mobile-app/app/components/SummaryTitle.tsx
@@ -7,10 +7,16 @@ import { RandomAvatar } from "@screens/AppNavigator/screens/Portfolio/components
import { AddressType } from "@waveshq/walletkit-ui/dist/store";
import { LocalAddress, WhitelistedAddress } from "@store/userPreferences";
import { DomainType } from "@contexts/DomainContext";
-import { LinearGradient } from "expo-linear-gradient";
+
+import {
+ AddressType as JellyfishAddressType,
+ getAddressType,
+} from "@waveshq/walletkit-core";
+import { useNetworkContext } from "@waveshq/walletkit-ui";
import { View } from ".";
import { ThemedTextV2, ThemedViewV2 } from "./themed";
import { EVMLinearGradient } from "./EVMLinearGradient";
+import { AddressEvmTag } from "./AddressEvmTag";
interface ISummaryTitleProps {
title: string;
@@ -33,6 +39,7 @@ export function SummaryTitle(props: ISummaryTitleProps): JSX.Element {
const IconA = getNativeIcon(props.iconA);
const IconB =
props.iconB !== undefined ? getNativeIcon(props.iconB) : undefined;
+ const { networkName } = useNetworkContext();
return (
<>
@@ -127,60 +134,47 @@ export function SummaryTitle(props: ISummaryTitleProps): JSX.Element {
>
{props.customToAddressTitle ?? translate("screens/common", "To")}
- {/* TODO @chloe cater for selection of evm addr from addr pair */}
+
+ {/* Checks if selected address is a Whitelisted EVM address */}
{(props.matchedAddress as WhitelistedAddress)?.addressDomainType ===
- DomainType.EVM ? (
-
- {props.addressType === AddressType.WalletAddress && (
-
-
-
- )}
-
- {props.toAddressLabel != null &&
- props.toAddressLabel.length > 0
- ? props.toAddressLabel
- : props.toAddress}
-
-
+ <>
+ {props.addressType === AddressType.WalletAddress && (
+
+
+
+ )}
+
+ {props.toAddressLabel}
+
+ >
+
) : (
+ // Whitelisted address - DVM
{props.addressType === AddressType.WalletAddress && (
-
-
+
+
)}
- {props.toAddressLabel != null &&
- props.toAddressLabel.length > 0
- ? props.toAddressLabel
- : props.toAddress}
+ {props.toAddressLabel}
)}
diff --git a/mobile-app/app/hooks/useWalletAddress.ts b/mobile-app/app/hooks/useWalletAddress.ts
index 8d6a9f2095..18bd7b9c7b 100644
--- a/mobile-app/app/hooks/useWalletAddress.ts
+++ b/mobile-app/app/hooks/useWalletAddress.ts
@@ -4,6 +4,7 @@ import { useCallback } from "react";
export interface WalletAddressI {
dvm: string;
evm: string;
+ generatedLabel: string;
}
export function useWalletAddress(): {
@@ -19,7 +20,8 @@ export function useWalletAddress(): {
const account = wallet.get(i);
const dvm = await account.getAddress();
const evm = await account.getEvmAddress();
- addresses.push({ dvm, evm });
+ const generatedLabel = `Address ${i + 1}`;
+ addresses.push({ dvm, evm, generatedLabel });
}
return addresses;
}, [wallet, addressLength]);
diff --git a/mobile-app/app/screens/AppNavigator/screens/Portfolio/components/AddressRow.tsx b/mobile-app/app/screens/AppNavigator/screens/Portfolio/components/AddressRow.tsx
index 02802c8ae3..2167c8d30c 100644
--- a/mobile-app/app/screens/AppNavigator/screens/Portfolio/components/AddressRow.tsx
+++ b/mobile-app/app/screens/AppNavigator/screens/Portfolio/components/AddressRow.tsx
@@ -8,28 +8,27 @@ import {
ThemedTouchableOpacity,
ThemedViewV2,
} from "@components/themed";
-import { RandomAvatar } from "@screens/AppNavigator/screens/Portfolio/components/RandomAvatar";
import { WalletTextInputV2 } from "@components/WalletTextInputV2";
import { Control, Controller } from "react-hook-form";
import { NetworkName } from "@defichain/jellyfish-network";
import { fromAddress } from "@defichain/jellyfish-address";
import {
LocalAddress,
- WhitelistedAddress,
selectAllLabeledWalletAddress,
+ WhitelistedAddress,
} from "@store/userPreferences";
import { debounce } from "lodash";
import { useEffect, useMemo, useState } from "react";
import { useSelector } from "react-redux";
import { RootState } from "@store";
-import { WalletAddressI, useWalletAddress } from "@hooks/useWalletAddress";
+import { useWalletAddress, WalletAddressI } from "@hooks/useWalletAddress";
import { DomainType, useDomainContext } from "@contexts/DomainContext";
-import { LinearGradient } from "expo-linear-gradient";
import {
- getAddressType,
AddressType as JellyfishAddressType,
+ getAddressType,
} from "@waveshq/walletkit-core";
-import { Text } from "@components";
+import { RandomAvatar } from "@screens/AppNavigator/screens/Portfolio/components/RandomAvatar";
+import { AddressEvmTag } from "@components/AddressEvmTag";
export function AddressRow({
control,
@@ -47,6 +46,7 @@ export function AddressRow({
onlyLocalAddress,
matchedAddress,
setMatchedAddress,
+ setAddressLabel,
}: {
control: Control;
networkName: NetworkName;
@@ -65,6 +65,7 @@ export function AddressRow({
onlyLocalAddress?: boolean;
matchedAddress?: LocalAddress | WhitelistedAddress | undefined;
setMatchedAddress?: (address?: LocalAddress | WhitelistedAddress) => void;
+ setAddressLabel?: React.Dispatch>;
}): JSX.Element {
const { fetchWalletAddresses } = useWalletAddress();
const { domain } = useDomainContext();
@@ -94,6 +95,15 @@ export function AddressRow({
return true;
}, [onlyLocalAddress, addressType, address]);
+ const addressObj = jellyfishWalletAddress.find(
+ (e: WalletAddressI) => e.dvm === address || e.evm === address,
+ );
+
+ const displayAddressLabel =
+ matchedAddress?.label !== ""
+ ? matchedAddress?.label
+ : addressObj?.generatedLabel;
+
const debounceMatchAddress = debounce(() => {
// Check if address input field is not empty
if (address !== undefined && setMatchedAddress !== undefined) {
@@ -111,10 +121,6 @@ export function AddressRow({
return;
}
- const addressObj = jellyfishWalletAddress.find(
- (e: WalletAddressI) => e.dvm === address || e.evm === address,
- );
-
if (addressObj) {
// Your addresses - Unlabelled
setMatchedAddress({
@@ -145,6 +151,12 @@ export function AddressRow({
}
}, 200);
+ useEffect(() => {
+ if (setAddressLabel !== undefined) {
+ setAddressLabel(displayAddressLabel);
+ }
+ }, [displayAddressLabel]);
+
useEffect(() => {
debounceMatchAddress();
}, [address, addressBook]);
@@ -270,7 +282,7 @@ export function AddressRow({
{addressType !== undefined && (
<>
- {/* Verified tag for DVM/EVM address */}
+ {/* Verified tag for unsaved but verified DVM/EVM address */}
{addressType === AddressType.OthersButValid && (
<>
>
)}
+
+ {/* Whitelisted and Yours Addresses */}
{addressType !== AddressType.OthersButValid &&
validLocalAddress && (
<>
- {/* TODO @chloe cater for selection of evm addr from addr pair */}
+ {/* Checks if selected address is a Whitelisted EVM address */}
{(matchedAddress as WhitelistedAddress)?.addressDomainType ===
- DomainType.EVM ? (
- // || (matchedAddress as LocalAddress)?.evmAddress ?
-
- {/* TODO add avatar for after updating address book design */}
-
+ <>
+ {addressType === AddressType.WalletAddress && (
+
+
+
)}
- >
- {matchedAddress?.label || matchedAddress?.address}
-
-
+
+ {displayAddressLabel}
+
+ >
+
) : (
+ // Whitelisted address - DVM
- {matchedAddress?.label || matchedAddress?.address}
+ {displayAddressLabel}
)}
diff --git a/mobile-app/app/screens/AppNavigator/screens/Portfolio/components/AddressSelectionButtonV2.tsx b/mobile-app/app/screens/AppNavigator/screens/Portfolio/components/AddressSelectionButtonV2.tsx
index 6f046c97fa..2205c7272b 100644
--- a/mobile-app/app/screens/AppNavigator/screens/Portfolio/components/AddressSelectionButtonV2.tsx
+++ b/mobile-app/app/screens/AppNavigator/screens/Portfolio/components/AddressSelectionButtonV2.tsx
@@ -5,6 +5,9 @@ import {
} from "@components/themed";
import { tailwind } from "@tailwind";
import { useAddressLabel } from "@hooks/useAddressLabel";
+import { useWalletAddress, WalletAddressI } from "@hooks/useWalletAddress";
+import { useEffect, useState } from "react";
+import { useLogger } from "@shared-contexts/NativeLoggingProvider";
import { RandomAvatar } from "./RandomAvatar";
interface AddressSelectionButtonProps {
@@ -15,9 +18,33 @@ interface AddressSelectionButtonProps {
}
export function AddressSelectionButtonV2(
- props: AddressSelectionButtonProps
+ props: AddressSelectionButtonProps,
): JSX.Element {
const addressLabel = useAddressLabel(props.address);
+ const logger = useLogger();
+ const { fetchWalletAddresses } = useWalletAddress();
+ const [availableAddresses, setAvailableAddresses] = useState<
+ WalletAddressI[]
+ >([]);
+ const generatedAddressLabel = availableAddresses.find(
+ (address) => address.dvm === props.address,
+ )?.generatedLabel;
+
+ const displayAddressLabel =
+ addressLabel === "" || addressLabel === null
+ ? generatedAddressLabel
+ : addressLabel;
+
+ // Getting addresses
+ const fetchAddresses = async (): Promise => {
+ const addresses = await fetchWalletAddresses();
+ setAvailableAddresses(addresses);
+ };
+
+ useEffect(() => {
+ fetchAddresses().catch(logger.error);
+ }, [props.address]);
+
return (
- {addressLabel != null ? addressLabel : props.address}
+ {displayAddressLabel}
);
diff --git a/mobile-app/app/screens/AppNavigator/screens/Portfolio/components/BottomSheetAddressDetailV2.tsx b/mobile-app/app/screens/AppNavigator/screens/Portfolio/components/BottomSheetAddressDetailV2.tsx
index bc172161f1..135b8d5b21 100644
--- a/mobile-app/app/screens/AppNavigator/screens/Portfolio/components/BottomSheetAddressDetailV2.tsx
+++ b/mobile-app/app/screens/AppNavigator/screens/Portfolio/components/BottomSheetAddressDetailV2.tsx
@@ -20,11 +20,11 @@ import {
} from "@shared-contexts/WalletContext";
import { useLogger } from "@shared-contexts/NativeLoggingProvider";
import { BottomSheetFlatList } from "@gorhom/bottom-sheet";
-import { useThemeContext, useNetworkContext } from "@waveshq/walletkit-ui";
+import { useNetworkContext, useThemeContext } from "@waveshq/walletkit-ui";
import {
- wallet as walletReducer,
- hasTxQueued,
hasOceanTXQueued,
+ hasTxQueued,
+ wallet as walletReducer,
} from "@waveshq/walletkit-ui/dist/store";
import { useSelector } from "react-redux";
import { loans } from "@store/loans";
@@ -36,12 +36,12 @@ import {
setAddresses,
setUserPreferences,
} from "@store/userPreferences";
-import { useAddressLabel } from "@hooks/useAddressLabel";
import { useAppDispatch } from "@hooks/useAppDispatch";
import { openURL } from "@api/linking";
import { ThemedFlatListV2 } from "@components/themed/ThemedFlatListV2";
-import { WalletAddressI, useWalletAddress } from "@hooks/useWalletAddress";
+import { useWalletAddress, WalletAddressI } from "@hooks/useWalletAddress";
import { DomainType, useDomainContext } from "@contexts/DomainContext";
+import { useAddressLabel } from "@hooks/useAddressLabel";
import { RandomAvatar } from "./RandomAvatar";
interface BottomSheetAddressDetailProps {
@@ -183,7 +183,6 @@ export const BottomSheetAddressDetailV2 = (
) {
return;
}
-
dispatch(walletReducer.actions.setHasFetchedToken(false));
dispatch(loans.actions.setHasFetchedVaultsData(false));
await setIndex(index);
@@ -192,19 +191,22 @@ export const BottomSheetAddressDetailV2 = (
};
const AddressListItem = useCallback(
- // eslint-disable-next-line react/no-unused-prop-types
({
item,
index,
}: {
+ // eslint-disable-next-line react/no-unused-prop-types
item: WalletAddressI;
+ // eslint-disable-next-line react/no-unused-prop-types
index: number;
}): JSX.Element => {
const isSelected = item.dvm === props.address;
- const hasLabel =
- labeledAddresses?.[item.dvm]?.label != null &&
- labeledAddresses?.[item.dvm]?.label !== "";
const displayAddress = domain === DomainType.EVM ? item.evm : item.dvm;
+
+ // if no existing address label, then display label from generatedAddress key
+ const displayAddressLabel =
+ labeledAddresses?.[item.dvm]?.label ?? item.generatedLabel;
+
return (
- {hasLabel && (
-
-
- {labeledAddresses[item.dvm]?.label}
-
- {isSelected && (
-
- )}
-
- )}
- {isSelected && !hasLabel && (
+
+ {displayAddressLabel}
+
+ {isSelected && (
)}
+
+
await openURL(getAddressUrl(displayAddress))
@@ -349,6 +338,11 @@ export const BottomSheetAddressDetailV2 = (
const activeAddress = availableAddresses.find(
({ dvm }) => dvm === props.address,
);
+ const displayAddressLabel =
+ activeLabel === null
+ ? activeAddress?.generatedLabel
+ : labeledAddresses?.[props.address]?.label;
+
const activeDomainAddress =
domain === DomainType.DVM ? activeAddress?.dvm : activeAddress?.evm;
return (
@@ -356,18 +350,16 @@ export const BottomSheetAddressDetailV2 = (
style={tailwind("flex flex-col w-full px-5 py-2 items-center")}
>
- {activeLabel != null && (
-
-
- {activeLabel}
-
-
- )}
+
+
+ {displayAddressLabel}
+
+
onActiveAddressPress(activeDomainAddress ?? "")}
diff --git a/mobile-app/app/screens/AppNavigator/screens/Portfolio/components/CreateOrEditAddressLabelForm.tsx b/mobile-app/app/screens/AppNavigator/screens/Portfolio/components/CreateOrEditAddressLabelForm.tsx
index f0bf08b989..b359e48d28 100644
--- a/mobile-app/app/screens/AppNavigator/screens/Portfolio/components/CreateOrEditAddressLabelForm.tsx
+++ b/mobile-app/app/screens/AppNavigator/screens/Portfolio/components/CreateOrEditAddressLabelForm.tsx
@@ -106,6 +106,7 @@ export const CreateOrEditAddressLabelForm = memo(
const isSaveDisabled = (): boolean => {
if (
labelInput === undefined ||
+ labelInput === "" || // disable if label is empty or no change in label
labelInput === addressLabel?.label ||
labelInputErrorMessage !== ""
) {
diff --git a/mobile-app/app/screens/AppNavigator/screens/Portfolio/screens/AddressBookScreen.tsx b/mobile-app/app/screens/AppNavigator/screens/Portfolio/screens/AddressBookScreen.tsx
index 3f1aaf21af..a466304281 100644
--- a/mobile-app/app/screens/AppNavigator/screens/Portfolio/screens/AddressBookScreen.tsx
+++ b/mobile-app/app/screens/AppNavigator/screens/Portfolio/screens/AddressBookScreen.tsx
@@ -1,4 +1,4 @@
-import { View, Text } from "@components";
+import { View } from "@components";
import {
ThemedIcon,
ThemedSectionTitleV2,
@@ -13,11 +13,11 @@ import {
import { RootState } from "@store";
import {
LocalAddress,
- WhitelistedAddress,
selectAddressBookArray,
selectLocalWalletAddressArray,
setUserPreferences,
userPreferences,
+ WhitelistedAddress,
} from "@store/userPreferences";
import { getColor, tailwind } from "@tailwind";
import { translate } from "@translations";
@@ -38,7 +38,7 @@ import { debounce } from "lodash";
import { openURL } from "@api/linking";
import { Logging } from "@api";
import { useWalletContext } from "@shared-contexts/WalletContext";
-import { WalletAddressI, useWalletAddress } from "@hooks/useWalletAddress";
+import { useWalletAddress, WalletAddressI } from "@hooks/useWalletAddress";
import { useAppDispatch } from "@hooks/useAppDispatch";
import LightEmptyAddress from "@assets/images/empty-address-light.png";
import DarkEmptyAddress from "@assets/images/empty-address-dark.png";
@@ -47,14 +47,15 @@ import { useNavigatorScreenOptions } from "@hooks/useNavigatorScreenOptions";
import { SearchInput } from "@components/SearchInput";
import { RefreshIcon } from "@screens/WalletNavigator/assets/RefreshIcon";
import { DomainType } from "@contexts/DomainContext";
-import { LinearGradient } from "expo-linear-gradient";
+import { RandomAvatar } from "@screens/AppNavigator/screens/Portfolio/components/RandomAvatar";
+import { EvmTag } from "@components/EvmTag";
+import { useLogger } from "@shared-contexts/NativeLoggingProvider";
import { ButtonGroup } from "../../Dex/components/ButtonGroup";
import {
FavoriteCheckIcon,
FavoriteUnCheckIcon,
} from "../../Settings/assets/FavoriteIcon";
import { SettingsParamList } from "../../Settings/SettingsNavigator";
-import { RandomAvatar } from "../components/RandomAvatar";
type Props = StackScreenProps;
@@ -69,7 +70,8 @@ export function AddressBookScreen({ route, navigation }: Props): JSX.Element {
const { isLight } = useThemeContext();
const { network } = useNetworkContext();
const dispatch = useAppDispatch();
- // condition to hide icon from send page
+ const logger = useLogger();
+ // condition to hide icon if not from send page
const enableAddressSelect =
selectedAddress !== undefined && onAddressSelect !== undefined;
const userPreferencesFromStore = useSelector(
@@ -115,6 +117,16 @@ export function AddressBookScreen({ route, navigation }: Props): JSX.Element {
: ButtonGroupTabKey.Whitelisted,
);
+ const [availableAddresses, setAvailableAddresses] = useState<
+ WalletAddressI[]
+ >([]);
+
+ // Getting addresses
+ const fetchAddresses = async (): Promise => {
+ const addresses = await fetchWalletAddresses();
+ setAvailableAddresses(addresses);
+ };
+
useEffect(() => {
// combine redux store and jellyfish wallet
let isSubscribed = true;
@@ -225,6 +237,10 @@ export function AddressBookScreen({ route, navigation }: Props): JSX.Element {
});
};
+ useEffect(() => {
+ fetchAddresses().catch(logger.error);
+ }, []);
+
useEffect(() => {
// sync all store changes to local storage
const updateLocalStorage = async (): Promise => {
@@ -267,46 +283,28 @@ export function AddressBookScreen({ route, navigation }: Props): JSX.Element {
});
}, []);
- const AddressListItem = useCallback(
+ const WhitelistedAddressItem = useCallback(
({
selectedAddress,
onAddressSelect,
...props
}: {
- item: LocalAddress | WhitelistedAddress;
+ item: WhitelistedAddress;
index: number;
testIDSuffix: string;
selectedAddress?: string;
onAddressSelect?: (address: string) => void;
}): JSX.Element => {
const { item, index, testIDSuffix } = props;
- const isDisabledToSelect = !!(
- (
- enableAddressSelect &&
- activeButtonGroup === ButtonGroupTabKey.Whitelisted &&
- (item as WhitelistedAddress).addressDomainType ===
- addressDomainType &&
- addressDomainType === DomainType.EVM
- ) // disable address selection if its from the same EVM domain
- );
+ const isDisabledToSelect =
+ enableAddressSelect &&
+ activeButtonGroup === ButtonGroupTabKey.Whitelisted &&
+ (item as WhitelistedAddress).addressDomainType === addressDomainType &&
+ addressDomainType === DomainType.EVM; // disable address selection if its from the same EVM domain
- const onChangeAddress = (
- addressDetail: LocalAddress | WhitelistedAddress,
- ): void => {
+ const onChangeAddress = (addressDetail: WhitelistedAddress): void => {
if (onAddressSelect) {
- // for whitelisted address
- if (activeButtonGroup === ButtonGroupTabKey.Whitelisted) {
- onAddressSelect(addressDetail.address);
- } else {
- // for wallet address
- onAddressSelect(
- addressDomainType === DomainType.EVM
- ? (addressDetail as LocalAddress).evmAddress
- : addressDetail.address,
- );
- }
- } else {
- onDFIAddressClick();
+ onAddressSelect(addressDetail.address);
}
};
@@ -349,33 +347,27 @@ export function AddressBookScreen({ route, navigation }: Props): JSX.Element {
"flex-auto": Platform.OS === "web",
})}
>
- {activeButtonGroup === ButtonGroupTabKey.YourAddress ? (
-
-
-
- ) : (
-
- await onFavouriteAddress(item as WhitelistedAddress)
- }
- testID={`address_row_star_${index}_${testIDSuffix}`}
- disabled={enableAddressSelect}
- >
- {(item as WhitelistedAddress).isFavourite === true ? (
-
- ) : (
-
- )}
-
- )}
+
+ await onFavouriteAddress(item as WhitelistedAddress)
+ }
+ testID={`address_row_star_${index}_${testIDSuffix}`}
+ disabled={enableAddressSelect}
+ >
+ {item.isFavourite ? (
+
+ ) : (
+
+ )}
+
@@ -387,29 +379,14 @@ export function AddressBookScreen({ route, navigation }: Props): JSX.Element {
>
{item.label}
- {activeButtonGroup === ButtonGroupTabKey.Whitelisted &&
- (item as WhitelistedAddress).addressDomainType ===
- DomainType.EVM && (
-
-
- EVM
-
-
- )}
+ {(item as WhitelistedAddress).addressDomainType ===
+ DomainType.EVM && (
+
+ )}
)}
{/* for DFI address */}
- onChangeAddress(item)}
/>
{/* for EVM address */}
- {activeButtonGroup === ButtonGroupTabKey.YourAddress && (
- {
- await openURL(
- getAddressUrl((item as LocalAddress).evmAddress),
- );
- }}
- />
- )}
- {!enableAddressSelect &&
- activeButtonGroup === ButtonGroupTabKey.Whitelisted && (
+ {enableAddressSelect && (
+
- )}
+
+ )}
@@ -451,6 +420,109 @@ export function AddressBookScreen({ route, navigation }: Props): JSX.Element {
[filteredAddressBook, filteredWalletAddress, activeButtonGroup],
);
+ const YourAddressListItem = useCallback(
+ ({
+ selectedAddress,
+ onAddressSelect,
+ ...props
+ }: {
+ item: LocalAddress;
+ index: number;
+ testIDSuffix: string;
+ selectedAddress?: string;
+ onAddressSelect?: (address: string) => void;
+ }): JSX.Element => {
+ const { item, index, testIDSuffix } = props;
+
+ const generatedAddressLabel = availableAddresses.find(
+ (address) =>
+ address.dvm === item.address || address.evm === item.evmAddress,
+ )?.generatedLabel;
+ const displayAddressLabel =
+ item.label === "" ? generatedAddressLabel : item.label;
+
+ const onChangeAddress = (addressDetail: string): void => {
+ if (onAddressSelect) {
+ onAddressSelect(addressDetail);
+ }
+ };
+
+ const onDFIAddressClick = async () => {
+ await openURL(getAddressUrl(item.address));
+ };
+
+ return (
+ // Your Address card
+
+
+
+
+
+
+ {item.label !== "" ? (
+
+ {item.label}
+
+ ) : (
+
+ {displayAddressLabel}
+
+ )}
+
+
+
+
+ {/* DVM address card */}
+ {
+ onChangeAddress(item.address);
+ }}
+ enableAddressSelect={enableAddressSelect}
+ />
+ {/* EVM address card */}
+ {
+ onChangeAddress(item.evmAddress);
+ }}
+ enableAddressSelect={enableAddressSelect}
+ />
+
+
+
+
+ );
+ },
+ [filteredAddressBook, filteredWalletAddress, activeButtonGroup],
+ );
+
const goToAddAddressForm = (): void => {
navigation.navigate({
name: "AddOrEditAddressBookScreen",
@@ -587,29 +659,41 @@ export function AddressBookScreen({ route, navigation }: Props): JSX.Element {
) : (
<>
+ {/* Search address */}
{!isSearchFocus && searchString?.trim().length === 0 && (
)}
- {(activeButtonGroup === ButtonGroupTabKey.Whitelisted
- ? filteredAddressBook
- : filteredWalletAddress
- ).map((item: LocalAddress | WhitelistedAddress, index: number) => (
-
- ))}
+
+ {/* wWhitelisted address tab */}
+ {activeButtonGroup === ButtonGroupTabKey.Whitelisted &&
+ filteredAddressBook.map(
+ (item: WhitelistedAddress, index: number) => (
+
+ ),
+ )}
+
+ {/* Your address tab */}
+ {activeButtonGroup === ButtonGroupTabKey.YourAddress &&
+ filteredWalletAddress.map((item: LocalAddress, index: number) => (
+
+ ))}
>
)}
@@ -684,7 +768,7 @@ export function DiscoverWalletAddressV2({
);
}
-function YourAddressLink({
+function WhitelistedAddressLink({
disabled,
onClick,
address,
@@ -729,3 +813,55 @@ function YourAddressLink({
);
}
+
+function YourAddressLink({
+ disabled,
+ onClick,
+ address,
+ isEvmAddress,
+ testIDSuffix,
+ enableAddressSelect,
+}: {
+ disabled?: boolean;
+ onClick: () => Promise;
+ address: string;
+ isEvmAddress?: boolean;
+ testIDSuffix: string;
+ enableAddressSelect: boolean;
+}) {
+ return (
+
+
+
+ {address}
+
+ {isEvmAddress && }
+
+ {enableAddressSelect && (
+
+ )}
+
+ );
+}
diff --git a/mobile-app/app/screens/AppNavigator/screens/Portfolio/screens/SendScreen.tsx b/mobile-app/app/screens/AppNavigator/screens/Portfolio/screens/SendScreen.tsx
index 3621325055..d78d3b90b4 100644
--- a/mobile-app/app/screens/AppNavigator/screens/Portfolio/screens/SendScreen.tsx
+++ b/mobile-app/app/screens/AppNavigator/screens/Portfolio/screens/SendScreen.tsx
@@ -102,6 +102,7 @@ export function SendScreen({ route, navigation }: Props): JSX.Element {
const [transactionCardStatus, setTransactionCardStatus] = useState(
TransactionCardStatus.Default,
);
+ const [addressLabel, setAddressLabel] = useState("");
// form
const { control, setValue, formState, getValues, trigger, watch } = useForm({
@@ -263,7 +264,7 @@ export function SendScreen({ route, navigation }: Props): JSX.Element {
amount: new BigNumber(values.amount),
amountInUsd: amountInUSDValue,
fee,
- toAddressLabel: matchedAddress?.label,
+ toAddressLabel: addressLabel,
addressType,
matchedAddress,
};
@@ -448,6 +449,7 @@ export function SendScreen({ route, navigation }: Props): JSX.Element {
onAddressType={setAddressType}
matchedAddress={matchedAddress}
setMatchedAddress={setMatchedAddress}
+ setAddressLabel={setAddressLabel}
/>
)}