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} /> )}