From 14d67954cd54ef37a2125fb371f75bb01681e9c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Vytick=20Vytrhl=C3=ADk?= Date: Mon, 2 Dec 2024 21:27:35 +0100 Subject: [PATCH] feat(suite-native): enable solana via message system --- .../message-system/src/messageSystemTypes.ts | 1 + .../discovery/src/discoveryConfigSlice.ts | 3 ++- .../feature-flags/src/featureFlagsSlice.ts | 23 ++++++++++++------- .../feature-flags/src/useFeatureFlag.tsx | 7 ++++-- .../components/KillswitchMessageScreen.tsx | 3 +-- suite-native/message-system/src/index.ts | 1 + suite-native/message-system/src/selectors.ts | 21 +++++++++++++---- .../src/selectors.ts | 13 ++++++++--- .../src/components/FeatureFlags.tsx | 1 - 9 files changed, 52 insertions(+), 21 deletions(-) diff --git a/suite-common/message-system/src/messageSystemTypes.ts b/suite-common/message-system/src/messageSystemTypes.ts index 05c3d336c077..fc9d72c607ba 100644 --- a/suite-common/message-system/src/messageSystemTypes.ts +++ b/suite-common/message-system/src/messageSystemTypes.ts @@ -24,6 +24,7 @@ export const Feature = { ethClaim: 'eth.staking.claim', firmwareRevisionCheck: 'security.firmware.check', firmwareHashCheck: 'security.firmware.hashCheck', + solanaMobile: 'mobile.solana', } as const; export type FeatureDomain = (typeof Feature)[keyof typeof Feature]; diff --git a/suite-native/discovery/src/discoveryConfigSlice.ts b/suite-native/discovery/src/discoveryConfigSlice.ts index cdbd9cc220fa..a2b2826b9ec5 100644 --- a/suite-native/discovery/src/discoveryConfigSlice.ts +++ b/suite-native/discovery/src/discoveryConfigSlice.ts @@ -27,6 +27,7 @@ import { TokensRootState, } from '@suite-native/tokens'; import { createWeakMapSelector, returnStableArrayIfEmpty } from '@suite-common/redux-utils'; +import { MessageSystemRootState } from '@suite-common/message-system'; type DiscoveryInfo = { startTimestamp: number; @@ -97,7 +98,7 @@ export const selectDiscoveryInfo = (state: DiscoveryConfigSliceRootState) => state.discoveryConfig.discoveryInfo; const createMemoizedSelector = createWeakMapSelector.withTypes< - DeviceRootState & DiscoveryConfigSliceRootState & FeatureFlagsRootState + DeviceRootState & DiscoveryConfigSliceRootState & FeatureFlagsRootState & MessageSystemRootState >(); const selectIsSolanaEnabled = createSelectIsFeatureFlagEnabled(FeatureFlag.IsSolanaEnabled); diff --git a/suite-native/feature-flags/src/featureFlagsSlice.ts b/suite-native/feature-flags/src/featureFlagsSlice.ts index 1c2196b0c96e..c950dc91589d 100644 --- a/suite-native/feature-flags/src/featureFlagsSlice.ts +++ b/suite-native/feature-flags/src/featureFlagsSlice.ts @@ -1,13 +1,14 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit'; import { isAndroid } from '@trezor/env-utils'; +import { MessageSystemRootState } from '@suite-common/message-system'; import { isDebugEnv, isDetoxTestBuild, isDevelopOrDebugEnv } from '@suite-native/config'; +import { selectIsSolanaFeatureEnabled } from '@suite-native/message-system'; export const FeatureFlag = { IsDeviceConnectEnabled: 'isDeviceConnectEnabled', IsRippleSendEnabled: 'isRippleSendEnabled', IsCardanoSendEnabled: 'isCardanoSendEnabled', - IsSolanaSendEnabled: 'isSolanaSendEnabled', IsRegtestEnabled: 'isRegtestEnabled', IsSolanaEnabled: 'IsSolanaEnabled', IsConnectPopupEnabled: 'IsConnectPopupEnabled', @@ -24,7 +25,6 @@ export const featureFlagsInitialState: FeatureFlagsState = { [FeatureFlag.IsDeviceConnectEnabled]: isAndroid() || isDebugEnv(), [FeatureFlag.IsRippleSendEnabled]: isAndroid() && isDevelopOrDebugEnv(), [FeatureFlag.IsCardanoSendEnabled]: isAndroid() && isDevelopOrDebugEnv(), - [FeatureFlag.IsSolanaSendEnabled]: isAndroid() && isDevelopOrDebugEnv(), [FeatureFlag.IsRegtestEnabled]: isDebugEnv() || isDetoxTestBuild(), [FeatureFlag.IsSolanaEnabled]: false, [FeatureFlag.IsConnectPopupEnabled]: isDevelopOrDebugEnv(), @@ -34,7 +34,6 @@ export const featureFlagsPersistedKeys: Array = [ FeatureFlag.IsDeviceConnectEnabled, FeatureFlag.IsRippleSendEnabled, FeatureFlag.IsCardanoSendEnabled, - FeatureFlag.IsSolanaSendEnabled, FeatureFlag.IsRegtestEnabled, FeatureFlag.IsSolanaEnabled, FeatureFlag.IsConnectPopupEnabled, @@ -50,12 +49,20 @@ export const featureFlagsSlice = createSlice({ }, }); -export const createSelectIsFeatureFlagEnabled = - (featureFlagKey: FeatureFlag) => (state: FeatureFlagsRootState) => - state.featureFlags[featureFlagKey]; +export const selectIsFeatureFlagEnabled = ( + state: FeatureFlagsRootState & MessageSystemRootState, + key: FeatureFlag, +) => { + if (key === FeatureFlag.IsSolanaEnabled) { + return selectIsSolanaFeatureEnabled(state) || state.featureFlags[key]; + } + + return state.featureFlags[key]; +}; -export const selectIsFeatureFlagEnabled = (state: FeatureFlagsRootState, key: FeatureFlag) => - state.featureFlags[key]; +export const createSelectIsFeatureFlagEnabled = + (featureFlagKey: FeatureFlag) => (state: FeatureFlagsRootState & MessageSystemRootState) => + selectIsFeatureFlagEnabled(state, featureFlagKey); export const { toggleFeatureFlag } = featureFlagsSlice.actions; export const featureFlagsReducer = featureFlagsSlice.reducer; diff --git a/suite-native/feature-flags/src/useFeatureFlag.tsx b/suite-native/feature-flags/src/useFeatureFlag.tsx index 3e0e207811a2..04a3919ef748 100644 --- a/suite-native/feature-flags/src/useFeatureFlag.tsx +++ b/suite-native/feature-flags/src/useFeatureFlag.tsx @@ -1,5 +1,7 @@ import { useDispatch, useSelector } from 'react-redux'; +import { MessageSystemRootState } from '@suite-common/message-system'; + import { FeatureFlag, FeatureFlagsRootState, @@ -12,8 +14,9 @@ type FeatureFlagHookReturnType = [boolean, () => void]; export const useFeatureFlag = (featureFlag: FeatureFlag): FeatureFlagHookReturnType => { const dispatch = useDispatch(); - const isFeatureFlagEnabled = useSelector((state: FeatureFlagsRootState) => - selectIsFeatureFlagEnabled(state, featureFlag), + const isFeatureFlagEnabled = useSelector( + (state: FeatureFlagsRootState & MessageSystemRootState) => + selectIsFeatureFlagEnabled(state, featureFlag), ); const toggleIsFeatureFlagEnabled = () => { diff --git a/suite-native/message-system/src/components/KillswitchMessageScreen.tsx b/suite-native/message-system/src/components/KillswitchMessageScreen.tsx index 239c2d9a1681..1ec16ec47e38 100644 --- a/suite-native/message-system/src/components/KillswitchMessageScreen.tsx +++ b/suite-native/message-system/src/components/KillswitchMessageScreen.tsx @@ -51,11 +51,10 @@ const iconVariantMap = { export const KillswitchMessageScreen = () => { const dispatch = useDispatch(); const openLink = useOpenLink(); + const { applyStyle } = useNativeStyles(); const killswitch = A.head(useSelector(selectActiveKillswitchMessages)); - const { applyStyle } = useNativeStyles(); - if (!killswitch) return null; const { diff --git a/suite-native/message-system/src/index.ts b/suite-native/message-system/src/index.ts index 0f9d1a2c7325..42e2857b83e2 100644 --- a/suite-native/message-system/src/index.ts +++ b/suite-native/message-system/src/index.ts @@ -1,3 +1,4 @@ export * from './messageSystemMiddleware'; export * from './components/MessageSystemBannerRenderer'; export * from './components/KillswitchMessageScreen'; +export * from './selectors'; diff --git a/suite-native/message-system/src/selectors.ts b/suite-native/message-system/src/selectors.ts index 708494d3de8c..c11a349a2a48 100644 --- a/suite-native/message-system/src/selectors.ts +++ b/suite-native/message-system/src/selectors.ts @@ -1,9 +1,22 @@ -import { createMemoizedSelector, selectActiveFeatureMessages } from '@suite-common/message-system'; +import { + createMemoizedSelector, + Feature, + MessageSystemRootState, + selectActiveFeatureMessages, + selectIsFeatureEnabled, +} from '@suite-common/message-system'; export const selectActiveKillswitchMessages = createMemoizedSelector( [selectActiveFeatureMessages], messages => - messages.filter( - m => m.feature?.filter(item => item.domain === 'killswitch' && item.flag) ?? false, - ), + messages.filter(m => { + const killswitchFeatures = m.feature?.filter( + item => item.domain === 'killswitch' && item?.flag, + ); + + return (killswitchFeatures?.length ?? 0) > 0; + }), ); + +export const selectIsSolanaFeatureEnabled = (state: MessageSystemRootState) => + selectIsFeatureEnabled(state, Feature.solanaMobile); diff --git a/suite-native/module-accounts-management/src/selectors.ts b/suite-native/module-accounts-management/src/selectors.ts index 8aa4667f16fc..bd7aca5ade5a 100644 --- a/suite-native/module-accounts-management/src/selectors.ts +++ b/suite-native/module-accounts-management/src/selectors.ts @@ -1,5 +1,6 @@ import { D, pipe } from '@mobily/ts-belt'; +import { MessageSystemRootState } from '@suite-common/message-system'; import { NetworkSymbol, getNetworkType, networks } from '@suite-common/wallet-config'; import { FeatureFlagsRootState, @@ -22,18 +23,24 @@ export const selectIsNetworkSendFlowEnabled = ( if (PRODUCTION_SEND_COINS_WHITELIST.includes(networkSymbol)) return true; - const isRippleSendEnabled = selectIsFeatureFlagEnabled(state, FeatureFlag.IsRippleSendEnabled); + const isRippleSendEnabled = selectIsFeatureFlagEnabled( + state as FeatureFlagsRootState & MessageSystemRootState, + FeatureFlag.IsRippleSendEnabled, + ); if (isRippleSendEnabled && networkType === 'ripple') return true; const isCardanoSendEnabled = selectIsFeatureFlagEnabled( - state, + state as FeatureFlagsRootState & MessageSystemRootState, FeatureFlag.IsCardanoSendEnabled, ); if (isCardanoSendEnabled && networkType === 'cardano') return true; - const isSolanaSendEnabled = selectIsFeatureFlagEnabled(state, FeatureFlag.IsSolanaSendEnabled); + const isSolanaSendEnabled = selectIsFeatureFlagEnabled( + state as FeatureFlagsRootState & MessageSystemRootState, + FeatureFlag.IsSolanaEnabled, + ); if (isSolanaSendEnabled && networkType === 'solana') return true; diff --git a/suite-native/module-dev-utils/src/components/FeatureFlags.tsx b/suite-native/module-dev-utils/src/components/FeatureFlags.tsx index c8040d4982d2..d64b2e534b78 100644 --- a/suite-native/module-dev-utils/src/components/FeatureFlags.tsx +++ b/suite-native/module-dev-utils/src/components/FeatureFlags.tsx @@ -5,7 +5,6 @@ const featureFlagsTitleMap = { [FeatureFlagEnum.IsDeviceConnectEnabled]: 'Connect device', [FeatureFlagEnum.IsRippleSendEnabled]: 'Ripple send', [FeatureFlagEnum.IsCardanoSendEnabled]: 'Cardano send', - [FeatureFlagEnum.IsSolanaSendEnabled]: 'Solana send', [FeatureFlagEnum.IsRegtestEnabled]: 'Regtest', [FeatureFlagEnum.IsSolanaEnabled]: 'Solana', [FeatureFlagEnum.IsConnectPopupEnabled]: 'Connect Popup',