Skip to content

Commit

Permalink
feat(core): feature flag evm (#4056)
Browse files Browse the repository at this point in the history
* chore(ops): bump packages to display changi (#4030)

* chore(ops): bump to add changi network

* chore(ops): bump packages to display changi

* feat(ui-ux): add svg icons for sui and xchf tokens (#4031)

* feat(ui-ux): add svg icons for sui and xchf tokens

* fix invlalid svg props

* update sui svg to a flatter one

* fix rect prop

---------

Co-authored-by: JJ Adonis <[email protected]>

* fix(ui-ux): updated walletkit package to filter out burn token pool pair (#4033)

* fix(ui-ux): updated walletkit package to filter out burn token pool pair

* fix(e2e): network details

* chore(ops): bump walletkit (#4036)

* feat(core): feature flag evm

* add feature flag

* feat(core): hide evm in address book

* fix maximum depth

* disable sending to evm address

* rm comment

---------

Co-authored-by: Lyka Labrada <[email protected]>
Co-authored-by: JJ Adonis <[email protected]>
Co-authored-by: Chloe <[email protected]>
  • Loading branch information
4 people authored Oct 16, 2023
1 parent 21c99d2 commit 7413d85
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 550 deletions.
6 changes: 5 additions & 1 deletion mobile-app/app/contexts/DomainContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import React, {
PropsWithChildren,
} from "react";
import { useLogger } from "@shared-contexts/NativeLoggingProvider";
import { useFeatureFlagContext } from "./FeatureFlagContext";

interface DomainLoader {
isDomainLoaded: boolean;
Expand Down Expand Up @@ -52,6 +53,7 @@ export function useDomain({ api }: DomainContextI): DomainLoader {

interface Domain {
domain: NonNullable<DomainType>;
isEvmFeatureEnabled: boolean;
setDomain: (domain: NonNullable<DomainType>) => Promise<void>;
}

Expand All @@ -64,6 +66,7 @@ export function useDomainContext(): Domain {
export function DomainProvider(
props: DomainContextI & PropsWithChildren<any>,
): JSX.Element | null {
const { isFeatureAvailable } = useFeatureFlagContext();
const { api } = props;
const { domain } = useDomain({ api });
const [currentDomain, setCurrentDomain] =
Expand All @@ -89,7 +92,8 @@ export function DomainProvider(
};

const context: Domain = {
domain: currentDomain,
domain: isFeatureAvailable("evm") ? currentDomain : DomainType.DVM,
isEvmFeatureEnabled: isFeatureAvailable("evm"),
setDomain,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import {
TokenListType,
} from "@screens/AppNavigator/screens/Dex/CompositeSwap/SwapTokenSelectionScreen";
import { ConvertDirection, ScreenName } from "@screens/enum";
import { DomainType } from "@contexts/DomainContext";
import { DomainType, useDomainContext } from "@contexts/DomainContext";
import { NetworkDetails } from "../Settings/screens/NetworkDetails";
import { PortfolioScreen } from "./PortfolioScreen";
import { ReceiveScreen } from "./screens/ReceiveScreen";
Expand Down Expand Up @@ -192,6 +192,7 @@ const PortfolioStack = createStackNavigator<PortfolioParamList>();
export function PortfolioNavigator(): JSX.Element {
const navigation = useNavigation<NavigationProp<PortfolioParamList>>();
const { isLight } = useThemeContext();
const { isEvmFeatureEnabled } = useDomainContext();
const goToNetworkSelect = (): void => {
navigation.navigate("NetworkSelectionScreenPortfolio");
};
Expand Down Expand Up @@ -239,7 +240,8 @@ export function PortfolioNavigator(): JSX.Element {
"flex flex-row bg-transparent items-center w-full",
)}
>
<DomainSwitch testID="domain_switch" />
{isEvmFeatureEnabled && <DomainSwitch testID="domain_switch" />}

<HeaderSettingButton />
</View>
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export interface ActionButtonsProps {

export function ActionButtons(): JSX.Element {
const { isFeatureAvailable } = useFeatureFlagContext();
const { domain } = useDomainContext();
const { domain, isEvmFeatureEnabled } = useDomainContext();
const isEvmDomain = domain === DomainType.EVM;

const { dvmTokens, evmTokens } = useTokenBalance();
Expand Down Expand Up @@ -191,15 +191,17 @@ export function ActionButtons(): JSX.Element {
}
/>
)}
<ActionButton
name={translate("components/ActionButtons", "Convert")}
iconSize={28}
testID="convert_button"
onPress={() => {
navigateToTokenSelectionScreen(TokenListType.From);
}}
isEvmDomain
/>
{isEvmFeatureEnabled && (
<ActionButton
name={translate("components/ActionButtons", "Convert")}
iconSize={28}
testID="convert_button"
onPress={() => {
navigateToTokenSelectionScreen(TokenListType.From);
}}
isEvmDomain
/>
)}

{!isEvmDomain && (
<>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
} from "@store/userPreferences";
import { getColor, tailwind } from "@tailwind";
import { translate } from "@translations";
import { createRef, useCallback, useEffect, useState } from "react";
import { createRef, useCallback, useEffect, useState, useMemo } from "react";
import {
Platform,
ScrollView,
Expand All @@ -46,7 +46,7 @@ import { ButtonV2 } from "@components/ButtonV2";
import { useNavigatorScreenOptions } from "@hooks/useNavigatorScreenOptions";
import { SearchInput } from "@components/SearchInput";
import { RefreshIcon } from "@screens/WalletNavigator/assets/RefreshIcon";
import { DomainType } from "@contexts/DomainContext";
import { DomainType, useDomainContext } from "@contexts/DomainContext";
import { RandomAvatar } from "@screens/AppNavigator/screens/Portfolio/components/RandomAvatar";
import { EvmTag } from "@components/EvmTag";
import { useLogger } from "@shared-contexts/NativeLoggingProvider";
Expand All @@ -69,6 +69,7 @@ export function AddressBookScreen({ route, navigation }: Props): JSX.Element {
route.params;
const { isLight } = useThemeContext();
const { network } = useNetworkContext();
const { isEvmFeatureEnabled } = useDomainContext();
const dispatch = useAppDispatch();
const logger = useLogger();
// condition to hide icon if not from send page
Expand All @@ -77,9 +78,19 @@ export function AddressBookScreen({ route, navigation }: Props): JSX.Element {
const userPreferencesFromStore = useSelector(
(state: RootState) => state.userPreferences,
);
const addressBook: WhitelistedAddress[] = useSelector((state: RootState) =>
selectAddressBookArray(state.userPreferences),
const whitelistedAddresses: WhitelistedAddress[] = useSelector(
(state: RootState) => selectAddressBookArray(state.userPreferences),
);

const addressBook = useMemo(() => {
return whitelistedAddresses?.filter((addr) => {
return (
isEvmFeatureEnabled ||
(!isEvmFeatureEnabled && addr.addressDomainType === DomainType.DVM)
);
});
}, [whitelistedAddresses]);

const walletAddressFromStore: LocalAddress[] = useSelector(
(state: RootState) => selectLocalWalletAddressArray(state.userPreferences),
); // not all wallet address are stored in userPreference
Expand Down Expand Up @@ -454,71 +465,81 @@ export function AddressBookScreen({ route, navigation }: Props): JSX.Element {

return (
// Your Address card
<ThemedViewV2
key={item.address}
light={tailwind("bg-mono-light-v2-00")}
dark={tailwind("bg-mono-dark-v2-00")}
style={tailwind("py-4.5 pl-5 pr-4 mb-2 rounded-lg-v2 ")}
testID={`address_row_${index}_${testIDSuffix}`}
<TouchableOpacity
activeOpacity={0.7}
onPress={() => onChangeAddress(item.address)}
disabled={isEvmFeatureEnabled}
>
<View
style={tailwind("flex flex-row items-center flex-grow", {
"flex-auto": Platform.OS === "web",
})}
<ThemedViewV2
key={item.address}
light={tailwind("bg-mono-light-v2-00")}
dark={tailwind("bg-mono-dark-v2-00")}
style={tailwind("py-4.5 pl-5 pr-4 mb-2 rounded-lg-v2 ")}
testID={`address_row_${index}_${testIDSuffix}`}
>
<View style={tailwind("flex flex-row items-center flex-auto")}>
<View style={tailwind("flex flex-auto")}>
<View
style={tailwind("flex flex-row justify-between items-center")}
>
<TouchableOpacity
activeOpacity={0.7}
onPress={onDFIAddressClick}
style={tailwind("flex flex-row items-center")}
>
{item.label !== "" ? (
<ThemedTextV2
style={tailwind("font-semibold-v2 text-sm min-w-0")}
testID={`address_row_label_${index}_${testIDSuffix}`}
>
{item.label}
</ThemedTextV2>
) : (
<ThemedTextV2
style={tailwind("font-semibold-v2 text-sm min-w-0")}
testID={`address_row_label_${index}_${testIDSuffix}`}
>
{displayAddressLabel}
</ThemedTextV2>
<View
style={tailwind("flex flex-row items-center flex-grow", {
"flex-auto": Platform.OS === "web",
})}
>
<View style={tailwind("flex flex-row items-center flex-auto")}>
<View style={tailwind("flex flex-auto")}>
<View
style={tailwind(
"flex flex-row justify-between items-center",
)}
</TouchableOpacity>
<RandomAvatar name={item.address} size={24} />
</View>
>
<TouchableOpacity
activeOpacity={0.7}
onPress={onDFIAddressClick}
style={tailwind("flex flex-row items-center")}
>
{item.label !== "" ? (
<ThemedTextV2
style={tailwind("font-semibold-v2 text-sm min-w-0")}
testID={`address_row_label_${index}_${testIDSuffix}`}
>
{item.label}
</ThemedTextV2>
) : (
<ThemedTextV2
style={tailwind("font-semibold-v2 text-sm min-w-0")}
testID={`address_row_label_${index}_${testIDSuffix}`}
>
{displayAddressLabel}
</ThemedTextV2>
)}
</TouchableOpacity>
<RandomAvatar name={item.address} size={24} />
</View>

{/* DVM address card */}
<YourAddressLink
address={item.address}
testIDSuffix={`${index}_${testIDSuffix}`}
onClick={async () => {
onChangeAddress(item.address);
}}
enableAddressSelect={enableAddressSelect}
/>
{/* EVM address card */}
<YourAddressLink
disabled={addressDomainType === DomainType.EVM}
testIDSuffix={`${index}_${testIDSuffix}_EVM`}
address={(item as LocalAddress).evmAddress}
isEvmAddress
onClick={async () => {
onChangeAddress(item.evmAddress);
}}
enableAddressSelect={enableAddressSelect}
/>
{/* DVM address card */}
<YourAddressLink
address={item.address}
testIDSuffix={`${index}_${testIDSuffix}`}
onClick={async () => {
onChangeAddress(item.address);
}}
enableAddressSelect={enableAddressSelect}
/>
{/* EVM address card */}
{isEvmFeatureEnabled && (
<YourAddressLink
disabled={addressDomainType === DomainType.EVM}
testIDSuffix={`${index}_${testIDSuffix}_EVM`}
address={(item as LocalAddress).evmAddress}
isEvmAddress
onClick={async () => {
onChangeAddress(item.evmAddress);
}}
enableAddressSelect={enableAddressSelect}
/>
)}
</View>
</View>
</View>
</View>
</ThemedViewV2>
</ThemedViewV2>
</TouchableOpacity>
);
},
[filteredAddressBook, filteredWalletAddress, activeButtonGroup],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ enum InlineTextStatus {
export function ConvertScreen(props: Props): JSX.Element {
const { getTokenPrice } = useTokenPrice();
const { isLight } = useThemeContext();
const { domain } = useDomainContext();
const { domain, isEvmFeatureEnabled } = useDomainContext();
const client = useWhaleApiClient();
const logger = useLogger();
const tokens = useSelector((state: RootState) =>
Expand Down Expand Up @@ -238,24 +238,21 @@ export function ConvertScreen(props: Props): JSX.Element {
},
};

// Display UTXO and the source Token
if (domain === DomainType.DVM && sourceToken.tokenId === "0") {
return [
defaultEvmTargetToken,
...dvmTokens.filter((token) => token.tokenId === "0_utxo"),
];
} else if (
// Display DFI (DVM)
domain === DomainType.DVM &&
sourceToken.tokenId === "0_utxo"
) {
return dvmTokens.filter((token) => token.tokenId === "0");
} else if (domain === DomainType.DVM) {
// Display EVM equivalent
return [defaultEvmTargetToken];
if (domain === DomainType.DVM) {
if (sourceToken.tokenId === "0") {
return isEvmFeatureEnabled
? [
defaultEvmTargetToken,
...dvmTokens.filter((token) => token.tokenId === "0_utxo"),
]
: dvmTokens.filter((token) => token.tokenId === "0_utxo");
} else if (sourceToken.tokenId === "0_utxo") {
return dvmTokens.filter((token) => token.tokenId === "0");
} else {
return isEvmFeatureEnabled ? [defaultEvmTargetToken] : [];
}
} else if (domain === DomainType.EVM && sourceToken.tokenId === "0_evm") {
// Display DFI (DVM)
return dvmTokens.filter((token) => token.tokenId === "0");
return isEvmFeatureEnabled ? [defaultEvmTargetToken] : [];
}
}

Expand Down Expand Up @@ -439,17 +436,27 @@ export function ConvertScreen(props: Props): JSX.Element {
/>
</View>

<TokenDropdownButton
tokenId={sourceToken.tokenId}
isEvmToken={sourceToken?.token.domainType === DomainType.EVM}
symbol={sourceToken.token.displaySymbol}
displayedTextSymbol={sourceToken.token.displayTextSymbol}
testID={TokenListType.From}
onPress={() => {
navigateToTokenSelectionScreen(TokenListType.From);
}}
status={TokenDropdownButtonStatus.Enabled}
/>
{isEvmFeatureEnabled && (
<TokenDropdownButton
tokenId={sourceToken.tokenId}
isEvmToken={sourceToken?.token.domainType === DomainType.EVM}
symbol={sourceToken.token.displaySymbol}
displayedTextSymbol={sourceToken.token.displayTextSymbol}
testID={TokenListType.From}
onPress={() => {
navigateToTokenSelectionScreen(TokenListType.From);
}}
status={TokenDropdownButtonStatus.Enabled}
/>
)}
{!isEvmFeatureEnabled && (
<FixedTokenButton
testID={TokenListType.From}
symbol={sourceToken.token.displaySymbol}
unit={sourceToken.token.displayTextSymbol}
isEvmToken={false}
/>
)}
</View>
</TransactionCard>

Expand Down Expand Up @@ -559,7 +566,7 @@ export function ConvertScreen(props: Props): JSX.Element {
/>
</View>

{sourceToken.tokenId === "0" && (
{sourceToken.tokenId === "0" && isEvmFeatureEnabled && (
<TokenDropdownButton
tokenId={targetToken?.tokenId}
isEvmToken={targetToken?.token.domainType === DomainType.EVM}
Expand All @@ -572,7 +579,8 @@ export function ConvertScreen(props: Props): JSX.Element {
status={TokenDropdownButtonStatus.Enabled}
/>
)}
{sourceToken.tokenId !== "0" && targetToken && (
{((sourceToken.tokenId !== "0" && targetToken) ||
(!isEvmFeatureEnabled && targetToken)) && (
<FixedTokenButton
testID={TokenListType.To}
symbol={targetToken.token.displaySymbol}
Expand Down
Loading

0 comments on commit 7413d85

Please sign in to comment.