diff --git a/app/src/main/java/com/tangem/tap/ApplicationEntryPoint.kt b/app/src/main/java/com/tangem/tap/ApplicationEntryPoint.kt index c68bec0ed0..ed9d07c577 100644 --- a/app/src/main/java/com/tangem/tap/ApplicationEntryPoint.kt +++ b/app/src/main/java/com/tangem/tap/ApplicationEntryPoint.kt @@ -39,7 +39,6 @@ import com.tangem.domain.wallets.builder.ColdUserWalletBuilder import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.domain.wallets.repository.WalletsRepository import com.tangem.features.onboarding.v2.OnboardingV2FeatureToggles -import com.tangem.operations.attestation.OnlineCardVerifier import com.tangem.tap.common.analytics.handlers.BlockchainExceptionHandler import com.tangem.tap.common.log.TangemAppLoggerInitializer import com.tangem.tap.domain.scanCard.CardScanningFeatureToggles @@ -138,8 +137,6 @@ interface ApplicationEntryPoint { fun getWorkerFactory(): HiltWorkerFactory - fun getOnlineCardVerifier(): OnlineCardVerifier - fun getColdUserWalletBuilderFactory(): ColdUserWalletBuilder.Factory fun getApiConfigsManager(): ApiConfigsManager diff --git a/app/src/main/java/com/tangem/tap/TangemApplication.kt b/app/src/main/java/com/tangem/tap/TangemApplication.kt index 337a48938a..ef784f8347 100644 --- a/app/src/main/java/com/tangem/tap/TangemApplication.kt +++ b/app/src/main/java/com/tangem/tap/TangemApplication.kt @@ -58,7 +58,6 @@ import com.tangem.domain.wallets.builder.ColdUserWalletBuilder import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.domain.wallets.repository.WalletsRepository import com.tangem.features.onboarding.v2.OnboardingV2FeatureToggles -import com.tangem.operations.attestation.OnlineCardVerifier import com.tangem.operations.attestation.api.TangemApiServiceSettings import com.tangem.tap.common.analytics.AnalyticsFactory import com.tangem.tap.common.analytics.api.AnalyticsHandlerBuilder @@ -78,7 +77,6 @@ import com.tangem.wallet.BuildConfig import dagger.hilt.EntryPoints import kotlinx.coroutines.* import org.rekotlin.Store -import kotlin.collections.set import com.tangem.tap.domain.walletconnect2.domain.LegacyWalletConnectRepository as WalletConnect2Repository lateinit var store: Store @@ -220,9 +218,6 @@ abstract class TangemApplication : Application(), ImageLoaderFactory, Configurat .setWorkerFactory(workerFactory) .build() - private val onlineCardVerifier: OnlineCardVerifier - get() = entryPoint.getOnlineCardVerifier() - private val coldUserWalletBuilderFactory: ColdUserWalletBuilder.Factory get() = entryPoint.getColdUserWalletBuilderFactory() @@ -367,7 +362,6 @@ abstract class TangemApplication : Application(), ImageLoaderFactory, Configurat clipboardManager = clipboardManager, settingsManager = settingsManager, uiMessageSender = uiMessageSender, - onlineCardVerifier = onlineCardVerifier, coldUserWalletBuilderFactory = coldUserWalletBuilderFactory, userTokensResponseStore = userTokensResponseStore, ), diff --git a/app/src/main/java/com/tangem/tap/data/DefaultCardSdkProvider.kt b/app/src/main/java/com/tangem/tap/data/DefaultCardSdkProvider.kt index 4661ff7c91..f1f6e969ee 100644 --- a/app/src/main/java/com/tangem/tap/data/DefaultCardSdkProvider.kt +++ b/app/src/main/java/com/tangem/tap/data/DefaultCardSdkProvider.kt @@ -16,16 +16,11 @@ import com.tangem.crypto.bip39.Wordlist import com.tangem.data.card.sdk.CardSdkOwner import com.tangem.data.card.sdk.CardSdkProvider import com.tangem.datasource.api.common.config.ApiConfig -import com.tangem.datasource.api.common.config.ApiEnvironment import com.tangem.datasource.api.common.config.managers.ApiConfigsManager -import com.tangem.datasource.local.preferences.AppPreferencesStore -import com.tangem.datasource.local.preferences.PreferencesKeys -import com.tangem.datasource.local.preferences.utils.getObjectMap import com.tangem.datasource.utils.AddHeadersInterceptor import com.tangem.datasource.utils.RequestHeader import com.tangem.operations.attestation.api.TangemApiServiceSettings import com.tangem.sdk.DefaultSessionViewDelegate -import com.tangem.sdk.api.featuretoggles.CardSdkFeatureToggles import com.tangem.sdk.extensions.* import com.tangem.sdk.nfc.AndroidNfcAvailabilityProvider import com.tangem.sdk.nfc.NfcManager @@ -34,13 +29,6 @@ import com.tangem.tap.foregroundActivityObserver import com.tangem.utils.coroutines.CoroutineDispatcherProvider import com.tangem.utils.info.AppInfoProvider import com.tangem.utils.version.AppVersionProvider -import com.tangem.wallet.BuildConfig -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.SupervisorJob -import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.runBlocking import javax.inject.Inject import javax.inject.Singleton @@ -55,11 +43,9 @@ import javax.inject.Singleton internal class DefaultCardSdkProvider @Inject constructor( private val analyticsExceptionHandler: AnalyticsExceptionHandler, private val dispatchers: CoroutineDispatcherProvider, - private val cardSdkFeatureToggles: CardSdkFeatureToggles, private val apiConfigsManager: ApiConfigsManager, appVersionProvider: AppVersionProvider, appInfoProvider: AppInfoProvider, - appPreferencesStore: AppPreferencesStore, ) : CardSdkProvider, CardSdkOwner { private val observer = Observer() @@ -70,27 +56,28 @@ internal class DefaultCardSdkProvider @Inject constructor( get() = holder?.sdk ?: tryToRegisterWithForegroundActivity() init { - if (BuildConfig.TESTER_MENU_ENABLED) { - appPreferencesStore.getObjectMap(PreferencesKeys.apiConfigsEnvironmentKey) - .map { - when (it[ApiConfig.ID.TangemTech.name]) { - ApiEnvironment.DEV, - ApiEnvironment.STAGE, - ApiEnvironment.MOCK, - -> false - ApiEnvironment.PROD, - null, - -> true - } - } - .distinctUntilChanged() - .onEach { isProd -> - holder?.let { - it.sdk.config.isTangemAttestationProdEnv = isProd - } - } - .launchIn(CoroutineScope(SupervisorJob() + dispatchers.main)) - } + // TODO: [REDACTED_TASK_KEY] Change API's base URL in CardSDK if API environment is changed + // if (BuildConfig.TESTER_MENU_ENABLED) { + // appPreferencesStore.getObjectMap(PreferencesKeys.apiConfigsEnvironmentKey) + // .map { + // when (it[ApiConfig.ID.TangemTech.name]) { + // ApiEnvironment.DEV, + // ApiEnvironment.STAGE, + // ApiEnvironment.MOCK, + // -> false + // ApiEnvironment.PROD, + // null, + // -> true + // } + // } + // .distinctUntilChanged() + // .onEach { isProd -> + // holder?.let { + // it.sdk.config.isTangemAttestationProdEnv = isProd + // } + // } + // .launchIn(CoroutineScope(SupervisorJob() + dispatchers.main)) + // } TangemApiServiceSettings.addInterceptors( AddHeadersInterceptor( @@ -188,10 +175,8 @@ internal class DefaultCardSdkProvider @Inject constructor( keystoreManager = keystoreManager, wordlist = Wordlist.getWordlist(activity), config = config.apply { - isNewOnlineAttestationEnabled = cardSdkFeatureToggles.isNewAttestationEnabled - val apiConfig = apiConfigsManager.getEnvironmentConfig(id = ApiConfig.ID.TangemTech) - isTangemAttestationProdEnv = apiConfig.environment == ApiEnvironment.PROD + tangemApiBaseUrl = apiConfig.baseUrl }, ) diff --git a/app/src/main/java/com/tangem/tap/di/domain/WalletsDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/WalletsDomainModule.kt index 684a7f0cf7..516a089afa 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/WalletsDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/WalletsDomainModule.kt @@ -15,10 +15,8 @@ import com.tangem.domain.wallets.repository.WalletsRepository import com.tangem.domain.wallets.usecase.* import com.tangem.feature.wallet.presentation.wallet.domain.IsWalletNFTEnabledSyncUseCase import com.tangem.feature.wallet.presentation.wallet.domain.WalletNameMigrationUseCase -import com.tangem.operations.attestation.OnlineCardVerifier import com.tangem.features.nft.NFTFeatureToggles import com.tangem.operations.attestation.CardArtworksProvider -import com.tangem.sdk.api.featuretoggles.CardSdkFeatureToggles import com.tangem.utils.coroutines.CoroutineDispatcherProvider import dagger.Module import dagger.Provides @@ -191,16 +189,8 @@ internal object WalletsDomainModule { @Provides @Singleton - fun provideGetCardImageUseCase( - onlineCardVerifier: OnlineCardVerifier, - cardArtworksProvider: CardArtworksProvider, - cardSdkFeatureToggles: CardSdkFeatureToggles, - ): GetCardImageUseCase { - return GetCardImageUseCase( - verifier = onlineCardVerifier, - cardArtworksProvider = cardArtworksProvider, - cardSdkFeatureToggles = cardSdkFeatureToggles, - ) + fun provideGetCardImageUseCase(cardArtworksProvider: CardArtworksProvider): GetCardImageUseCase { + return GetCardImageUseCase(cardArtworksProvider = cardArtworksProvider) } @Provides diff --git a/app/src/main/java/com/tangem/tap/domain/extensions/Card.kt b/app/src/main/java/com/tangem/tap/domain/extensions/Card.kt deleted file mode 100644 index 547dfbd6ce..0000000000 --- a/app/src/main/java/com/tangem/tap/domain/extensions/Card.kt +++ /dev/null @@ -1,47 +0,0 @@ -package com.tangem.tap.domain.extensions - -import com.tangem.common.extensions.toHexString -import com.tangem.common.services.Result -import com.tangem.domain.common.TwinCardNumber -import com.tangem.domain.common.getTwinCardNumber -import com.tangem.domain.models.scan.CardDTO -import com.tangem.domain.wallets.models.Artwork -import com.tangem.operations.attestation.CardArtworksProvider -import com.tangem.operations.attestation.OnlineCardVerifier -import com.tangem.operations.attestation.api.models.CardVerifyAndGetInfo - -fun CardDTO.signedHashesCount(): Int { - return wallets.sumOf { it.totalSignedHashes ?: 0 } -} - -suspend fun CardDTO.getOrLoadCardArtworkUrl( - cardInfo: Result? = null, - onlineCardVerifier: OnlineCardVerifier, -): String { - fun ifAnyError(): String { - return when { - cardId.startsWith(Artwork.SERGIO_CARD_ID) -> Artwork.SERGIO_CARD_URL - cardId.startsWith(Artwork.MARTA_CARD_ID) -> Artwork.MARTA_CARD_URL - else -> { - when (getTwinCardNumber()) { - TwinCardNumber.First -> Artwork.TWIN_CARD_1_URL - TwinCardNumber.Second -> Artwork.TWIN_CARD_2_URL - else -> Artwork.DEFAULT_IMG_URL - } - } - } - } - - return when (val cardInfoResult = cardInfo ?: onlineCardVerifier.getCardInfo(cardId, cardPublicKey)) { - is Result.Success -> { - val artworkId = cardInfoResult.data.artwork?.id - if (artworkId.isNullOrEmpty()) { - ifAnyError() - } else { - CardArtworksProvider.getUrlForArtwork(cardId, cardPublicKey.toHexString(), artworkId) - } - } - - is Result.Failure -> ifAnyError() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/cardsettings/model/CardSettingsModel.kt b/app/src/main/java/com/tangem/tap/features/details/ui/cardsettings/model/CardSettingsModel.kt index 3ae653038c..09a825389e 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/cardsettings/model/CardSettingsModel.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/cardsettings/model/CardSettingsModel.kt @@ -27,7 +27,6 @@ import com.tangem.tap.common.analytics.events.Settings import com.tangem.tap.common.extensions.dispatchDialogShow import com.tangem.tap.common.extensions.dispatchNavigationAction import com.tangem.tap.common.redux.AppDialog -import com.tangem.tap.domain.extensions.signedHashesCount import com.tangem.tap.features.details.ui.cardsettings.CardInfo import com.tangem.tap.features.details.ui.cardsettings.CardSettingsScreenState import com.tangem.tap.features.details.ui.cardsettings.api.CardSettingsComponent @@ -169,6 +168,8 @@ internal class CardSettingsModel @Inject constructor( } } + private fun CardDTO.signedHashesCount(): Int = wallets.sumOf { it.totalSignedHashes ?: 0 } + private fun handleClickingItem(item: CardInfo) { when (item) { is CardInfo.ChangeAccessCode -> { diff --git a/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphState.kt b/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphState.kt index 5cfc7781f2..1c696ac842 100644 --- a/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphState.kt +++ b/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphState.kt @@ -33,7 +33,6 @@ import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.domain.wallets.repository.WalletsRepository import com.tangem.features.onboarding.v2.OnboardingV2FeatureToggles import com.tangem.operations.attestation.CardArtworksProvider -import com.tangem.operations.attestation.OnlineCardVerifier import com.tangem.tap.domain.scanCard.CardScanningFeatureToggles import com.tangem.tap.domain.walletconnect2.domain.LegacyWalletConnectRepository import com.tangem.tap.domain.walletconnect2.domain.WalletConnectInteractor @@ -75,7 +74,6 @@ data class DaggerGraphState( val clipboardManager: ClipboardManager? = null, val settingsManager: SettingsManager? = null, val uiMessageSender: UiMessageSender? = null, - val onlineCardVerifier: OnlineCardVerifier? = null, val cardArworksProvider: CardArtworksProvider? = null, val coldUserWalletBuilderFactory: ColdUserWalletBuilder.Factory? = null, val userTokensResponseStore: UserTokensResponseStore? = null, diff --git a/core/config-toggles/src/main/assets/configs/feature_toggles_config.json b/core/config-toggles/src/main/assets/configs/feature_toggles_config.json index d63c340831..58acd094db 100644 --- a/core/config-toggles/src/main/assets/configs/feature_toggles_config.json +++ b/core/config-toggles/src/main/assets/configs/feature_toggles_config.json @@ -31,14 +31,6 @@ "name": "STAKING_CARDANO_ENABLED", "version": "undefined" }, - { - "name": "NEW_ARTWORK_LOADING", - "version": "5.25.0" - }, - { - "name": "NEW_ATTESTATION_ENABLED", - "version": "5.24.0" - }, { "name": "WALLET_CONNECT_REDESIGN_ENABLED", "version": "undefined" diff --git a/data/card/src/main/java/com/tangem/data/card/DefaultCardSdkConfigRepository.kt b/data/card/src/main/java/com/tangem/data/card/DefaultCardSdkConfigRepository.kt index 61be7f90d6..ddc431ebb6 100644 --- a/data/card/src/main/java/com/tangem/data/card/DefaultCardSdkConfigRepository.kt +++ b/data/card/src/main/java/com/tangem/data/card/DefaultCardSdkConfigRepository.kt @@ -72,6 +72,6 @@ internal class DefaultCardSdkConfigRepository( } override fun setTangemApiProdEnvFlag(flag: Boolean) { - sdk.config.isTangemAttestationProdEnv = flag + // TODO: [REDACTED_TASK_KEY] Change API's base URL in CardSDK if API environment is changed } } \ No newline at end of file diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetCardImageUseCase.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetCardImageUseCase.kt index 6b3f2f5ab8..dbee9b5cfb 100644 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetCardImageUseCase.kt +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetCardImageUseCase.kt @@ -1,7 +1,6 @@ package com.tangem.domain.wallets.usecase import com.tangem.common.card.FirmwareVersion -import com.tangem.common.extensions.toHexString import com.tangem.common.services.Result import com.tangem.domain.common.TwinCardNumber import com.tangem.domain.common.TwinsHelper @@ -9,20 +8,16 @@ import com.tangem.domain.models.ArtworkModel import com.tangem.domain.wallets.models.Artwork import com.tangem.operations.attestation.ArtworkSize import com.tangem.operations.attestation.CardArtworksProvider -import com.tangem.operations.attestation.OnlineCardVerifier -import com.tangem.sdk.api.featuretoggles.CardSdkFeatureToggles /** * Use case for getting card image url * - * @property verifier online card verifier + * @property cardArtworksProvider card artworks provider * [REDACTED_AUTHOR] */ class GetCardImageUseCase( - private val verifier: OnlineCardVerifier, private val cardArtworksProvider: CardArtworksProvider, - private val cardSdkFeatureToggles: CardSdkFeatureToggles, ) { /** @@ -38,39 +33,17 @@ class GetCardImageUseCase( firmwareVersion: FirmwareVersion, size: ArtworkSize = ArtworkSize.SMALL, ): ArtworkModel { - return if (cardSdkFeatureToggles.isNewArtworkLoadingEnabled) { - val result = cardArtworksProvider.getArtwork( - cardId = cardId, - cardPublicKey = cardPublicKey, - manufacturerName = manufacturerName, - firmwareVersion = firmwareVersion, - size = size, - ) - when (result) { - is Result.Failure -> ArtworkModel(null, getFallbackArtworkUrl(cardId)) - is Result.Success -> ArtworkModel(result.data, getFallbackArtworkUrl(cardId)) - } - } else { - ArtworkModel(null, getLegacyArtwork(cardId, cardPublicKey)) - } - } + val result = cardArtworksProvider.getArtwork( + cardId = cardId, + cardPublicKey = cardPublicKey, + manufacturerName = manufacturerName, + firmwareVersion = firmwareVersion, + size = size, + ) - private suspend fun getLegacyArtwork(cardId: String, cardPublicKey: ByteArray): String { - return when (val result = verifier.getCardInfo(cardId, cardPublicKey)) { - is Result.Success -> { - val artworkId = result.data.artwork?.id - if (artworkId.isNullOrEmpty()) { - getFallbackArtworkUrl(cardId) - } else { - CardArtworksProvider.getUrlForArtwork( - cardId = cardId, - cardPublicKey = cardPublicKey.toHexString(), - artworkId = artworkId, - ) - } - } - - is Result.Failure -> getFallbackArtworkUrl(cardId) + return when (result) { + is Result.Failure -> ArtworkModel(null, getFallbackArtworkUrl(cardId)) + is Result.Success -> ArtworkModel(result.data, getFallbackArtworkUrl(cardId)) } } diff --git a/gradle/tangem_dependencies.toml b/gradle/tangem_dependencies.toml index 3c032ea43e..65d8993bb1 100644 --- a/gradle/tangem_dependencies.toml +++ b/gradle/tangem_dependencies.toml @@ -7,7 +7,7 @@ tangemBlockchainSdk = "develop-1104" #tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds -tangemCardSdk = "develop-487" +tangemCardSdk = "develop-489" #tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^ tangemVico = "2.0.0-alpha.25-tangem12" #tangemVico = "0.0.1" # Keep it! - used for local builds ^ diff --git a/libs/tangem-sdk-api/src/main/kotlin/com/tangem/sdk/api/di/CardSdkModule.kt b/libs/tangem-sdk-api/src/main/kotlin/com/tangem/sdk/api/di/CardSdkModule.kt index 1f27687d60..513b751434 100644 --- a/libs/tangem-sdk-api/src/main/kotlin/com/tangem/sdk/api/di/CardSdkModule.kt +++ b/libs/tangem-sdk-api/src/main/kotlin/com/tangem/sdk/api/di/CardSdkModule.kt @@ -2,7 +2,6 @@ package com.tangem.sdk.api.di import com.tangem.domain.card.repository.CardSdkConfigRepository import com.tangem.operations.attestation.CardArtworksProvider -import com.tangem.operations.attestation.OnlineCardVerifier import dagger.Module import dagger.Provides import dagger.hilt.InstallIn @@ -15,13 +14,10 @@ internal object CardSdkModule { @Provides @Singleton - fun provideOnlineCardVerifier(): OnlineCardVerifier = OnlineCardVerifier() - - @Provides - @Singleton - fun provideCardArtworksProvider(sdkRepository: CardSdkConfigRepository): CardArtworksProvider = - CardArtworksProvider( - sdkRepository.sdk.config.isTangemAttestationProdEnv, - sdkRepository.sdk.secureStorage, + fun provideCardArtworksProvider(sdkRepository: CardSdkConfigRepository): CardArtworksProvider { + return CardArtworksProvider( + tangemApiBaseUrlProvider = { sdkRepository.sdk.config.tangemApiBaseUrl }, + secureStorage = sdkRepository.sdk.secureStorage, ) + } } \ No newline at end of file diff --git a/libs/tangem-sdk-api/src/main/kotlin/com/tangem/sdk/api/featuretoggles/CardSdkFeatureToggles.kt b/libs/tangem-sdk-api/src/main/kotlin/com/tangem/sdk/api/featuretoggles/CardSdkFeatureToggles.kt index 7eb52af432..95cc6b5096 100644 --- a/libs/tangem-sdk-api/src/main/kotlin/com/tangem/sdk/api/featuretoggles/CardSdkFeatureToggles.kt +++ b/libs/tangem-sdk-api/src/main/kotlin/com/tangem/sdk/api/featuretoggles/CardSdkFeatureToggles.kt @@ -5,9 +5,4 @@ package com.tangem.sdk.api.featuretoggles * [REDACTED_AUTHOR] */ -interface CardSdkFeatureToggles { - - val isNewAttestationEnabled: Boolean - - val isNewArtworkLoadingEnabled: Boolean -} \ No newline at end of file +interface CardSdkFeatureToggles \ No newline at end of file diff --git a/libs/tangem-sdk-api/src/main/kotlin/com/tangem/sdk/api/featuretoggles/DefaultCardSdkFeatureToggles.kt b/libs/tangem-sdk-api/src/main/kotlin/com/tangem/sdk/api/featuretoggles/DefaultCardSdkFeatureToggles.kt index 0a12b3ce37..56584647da 100644 --- a/libs/tangem-sdk-api/src/main/kotlin/com/tangem/sdk/api/featuretoggles/DefaultCardSdkFeatureToggles.kt +++ b/libs/tangem-sdk-api/src/main/kotlin/com/tangem/sdk/api/featuretoggles/DefaultCardSdkFeatureToggles.kt @@ -4,12 +4,5 @@ import com.tangem.core.configtoggle.feature.FeatureTogglesManager import javax.inject.Inject internal class DefaultCardSdkFeatureToggles @Inject constructor( - private val featureTogglesManager: FeatureTogglesManager, -) : CardSdkFeatureToggles { - - override val isNewAttestationEnabled: Boolean - get() = featureTogglesManager.isFeatureEnabled(name = "NEW_ATTESTATION_ENABLED") - - override val isNewArtworkLoadingEnabled: Boolean - get() = featureTogglesManager.isFeatureEnabled(name = "NEW_ARTWORK_LOADING") -} \ No newline at end of file + @Suppress("UnusedPrivateMember") private val featureTogglesManager: FeatureTogglesManager, +) : CardSdkFeatureToggles \ No newline at end of file