From 5987be96a7a365c03c067dd904ea777f7a81439e Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 13 Nov 2020 21:37:47 +0300 Subject: [PATCH 01/21] Updated on 2026-08-14 --- app/src/main/assets/dev_config_values.json | 16 +++++ app/src/main/assets/dev_features.json | 20 ++++++ .../tangem/tap/domain/config/Conditions.kt | 27 ++++++++ .../tangem/tap/domain/config/ConfigLoader.kt | 68 +++++++++++++++++++ .../tangem/tap/domain/config/JsonModels.kt | 36 ++++++++++ .../com/tangem/tap/domain/config/Models.kt | 45 ++++++++++++ 6 files changed, 212 insertions(+) create mode 100644 app/src/main/assets/dev_config_values.json create mode 100644 app/src/main/assets/dev_features.json create mode 100644 app/src/main/java/com/tangem/tap/domain/config/Conditions.kt create mode 100644 app/src/main/java/com/tangem/tap/domain/config/ConfigLoader.kt create mode 100644 app/src/main/java/com/tangem/tap/domain/config/JsonModels.kt create mode 100644 app/src/main/java/com/tangem/tap/domain/config/Models.kt diff --git a/app/src/main/assets/dev_config_values.json b/app/src/main/assets/dev_config_values.json new file mode 100644 index 0000000000..532adfd5c1 --- /dev/null +++ b/app/src/main/assets/dev_config_values.json @@ -0,0 +1,16 @@ +{ + "configValues": [ + { + "name": "coinMarketCapKey", + "value": "f6622117-c043-47a0-8975-9d673ce484de" + }, + { + "name": "moonPayApiKey", + "value": "pk_test_kc90oYTANy7UQdBavDKGfL4K9l6VEPE" + }, + { + "name": "moonPayApiSecretKey", + "value": "sk_test_V8w4M19LbDjjYOt170s0tGuvXAgyEb1C" + } + ] +} \ No newline at end of file diff --git a/app/src/main/assets/dev_features.json b/app/src/main/assets/dev_features.json new file mode 100644 index 0000000000..aa3fd4c598 --- /dev/null +++ b/app/src/main/assets/dev_features.json @@ -0,0 +1,20 @@ +{ + "features": [ + { + "name": "payIdCreationEnabled", + "value": false + }, + { + "name": "usePayId", + "value": false + }, + { + "name": "showWelcomeMessageAtStart", + "value": false + }, + { + "name": "useTopUp", + "value": false + } + ] +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/config/Conditions.kt b/app/src/main/java/com/tangem/tap/domain/config/Conditions.kt new file mode 100644 index 0000000000..b684bdfbb3 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/domain/config/Conditions.kt @@ -0,0 +1,27 @@ +package com.tangem.tap.domain.config + +import com.tangem.commands.Card +import java.util.* + +/** +[REDACTED_AUTHOR] + */ +interface Condition { + fun isMet(): Boolean +} + +class CardIsStart2CoinCondition(private val card: Card?) : Condition { + + override fun isMet(): Boolean = card?.cardData?.issuerName?.toLowerCase(Locale.US) == "start2coin" +} + +class ConditionsFactory { + companion object { + fun create(name: String): Condition? { + return when (name) { + Feature.payIdIsEnabled -> CardIsStart2CoinCondition(null) + else -> null + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/config/ConfigLoader.kt b/app/src/main/java/com/tangem/tap/domain/config/ConfigLoader.kt new file mode 100644 index 0000000000..372bf5e807 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/domain/config/ConfigLoader.kt @@ -0,0 +1,68 @@ +package com.tangem.tap.domain.config + +import android.content.Context +import com.squareup.moshi.JsonAdapter +import com.tangem.wallet.BuildConfig +import timber.log.Timber + +/** +[REDACTED_AUTHOR] + */ +interface ConfigLoader { + suspend fun loadConfig(onComplete: (Config) -> Unit) +} + + +interface NameResolver { + fun getFeaturesName(): String + fun getConfigValuesName(): String +} + +class ConfigNameResolver { + companion object { + fun get(): NameResolver = if (BuildConfig.DEBUG) dev() else prod() + + private fun dev(): NameResolver { + return object : NameResolver { + override fun getFeaturesName(): String = "dev_features" + override fun getConfigValuesName(): String = "dev_config_values" + } + } + + private fun prod(): NameResolver { + return object : NameResolver { + override fun getFeaturesName(): String = "prod_features" + override fun getConfigValuesName(): String = "prod_config_values" + + } + } + } +} + +class LocalLoader( + private val context: Context, + private val nameResolver: NameResolver, + private val adapter: JsonAdapter +) : ConfigLoader { + + override suspend fun loadConfig(onComplete: (Config) -> Unit) { + val config = try { + val jsonFeatures = readAssetAsString(nameResolver.getFeaturesName()) + var configModel = adapter.fromJson(jsonFeatures) + val features = configModel?.toFeatures(ConfigType.Local) ?: mutableMapOf() + + val jsonConfigValues = readAssetAsString(nameResolver.getConfigValuesName()) + configModel = adapter.fromJson(jsonConfigValues) + val configValues = configModel?.toConfigValues() ?: mutableMapOf() + Config(features, configValues) + } catch (ex: Exception) { + Timber.e(ex) + Config.empty() + } + onComplete(config) + } + + private fun readAssetAsString(fileName: String): String { + return context.assets.open("$fileName.json").bufferedReader().readText() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/config/JsonModels.kt b/app/src/main/java/com/tangem/tap/domain/config/JsonModels.kt new file mode 100644 index 0000000000..18e1e80766 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/domain/config/JsonModels.kt @@ -0,0 +1,36 @@ +package com.tangem.tap.domain.config + +/** +[REDACTED_AUTHOR] + */ + +interface BaseConfigModel { + val name: String + val value: V? +} + +class FeatureModel( + override val name: String, + override val value: Boolean? +) : BaseConfigModel + +class ConfigValueModel( + override val name: String, + override val value: String? +) : BaseConfigModel + +class ConfigModel(val features: List?, val configValues: List?) + +fun ConfigModel.toFeatures(type: ConfigType): MutableMap { + return features?.map { AppFeature(type, it, ConditionsFactory.create(it.name)) } + ?.associateBy { it.name } + ?.toMutableMap() + ?: mutableMapOf() +} + +fun ConfigModel.toConfigValues(): MutableMap { + return configValues?.map { ConfigurationValue(it.name, it.value) } + ?.associateBy { it.name } + ?.toMutableMap() ?: mutableMapOf() +} + diff --git a/app/src/main/java/com/tangem/tap/domain/config/Models.kt b/app/src/main/java/com/tangem/tap/domain/config/Models.kt new file mode 100644 index 0000000000..07a3bf28bb --- /dev/null +++ b/app/src/main/java/com/tangem/tap/domain/config/Models.kt @@ -0,0 +1,45 @@ +package com.tangem.tap.domain.config + +/** +[REDACTED_AUTHOR] + */ + +interface Feature { + val name: String + val type: ConfigType + fun isActive(): Boolean + fun reset() + fun updateCondition(condition: Condition?) + fun hasCondition(): Boolean + + companion object { + val payIdIsEnabled = "payIdIsEnabled" + } +} + +class AppFeature( + override val type: ConfigType, + private val featureModel: FeatureModel, + private var condition: Condition? +) : Feature { + override val name: String = featureModel.name + + override fun isActive(): Boolean { + return if (condition == null) featureModel.value ?: false + else condition!!.isMet() + } + + override fun reset() { + condition = null + } + + override fun updateCondition(condition: Condition?) { + if (type == ConfigType.Local) this.condition = condition + } + + override fun hasCondition(): Boolean { + return condition != null + } +} + +data class ConfigurationValue(val name: String, val value: String?) \ No newline at end of file From 5968cf338f0d3dde02a33d78ab647b388125d768 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 13 Nov 2020 21:38:54 +0300 Subject: [PATCH 02/21] Updated on 2026-08-14 --- app/build.gradle | 1 + .../tangem/tap/domain/config/ConfigLoader.kt | 32 +++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/app/build.gradle b/app/build.gradle index ae51a02977..bd0585009b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -98,6 +98,7 @@ dependencies { // Firebase implementation platform('com.google.firebase:firebase-bom:26.0.0') implementation 'com.google.firebase:firebase-crashlytics' + implementation 'com.google.firebase:firebase-config-ktx' implementation 'com.google.firebase:firebase-analytics-ktx' testImplementation 'junit:junit:4.13' diff --git a/app/src/main/java/com/tangem/tap/domain/config/ConfigLoader.kt b/app/src/main/java/com/tangem/tap/domain/config/ConfigLoader.kt index 372bf5e807..a9d07377cd 100644 --- a/app/src/main/java/com/tangem/tap/domain/config/ConfigLoader.kt +++ b/app/src/main/java/com/tangem/tap/domain/config/ConfigLoader.kt @@ -1,6 +1,8 @@ package com.tangem.tap.domain.config import android.content.Context +import com.google.firebase.ktx.Firebase +import com.google.firebase.remoteconfig.ktx.remoteConfig import com.squareup.moshi.JsonAdapter import com.tangem.wallet.BuildConfig import timber.log.Timber @@ -65,4 +67,34 @@ class LocalLoader( private fun readAssetAsString(fileName: String): String { return context.assets.open("$fileName.json").bufferedReader().readText() } +} + +class RemoteLoader( + private val nameResolver: NameResolver, + private val adapter: JsonAdapter +) : ConfigLoader { + + override suspend fun loadConfig(onComplete: (Config) -> Unit) { + val emptyConfig = Config.empty() + val remoteConfig = Firebase.remoteConfig + remoteConfig.fetchAndActivate().addOnCompleteListener { + if (it.isSuccessful) { + val config = remoteConfig.getValue(nameResolver.getFeaturesName()) + val jsonConfig = config.asString() + if (jsonConfig.isEmpty()) { + onComplete(emptyConfig) + return@addOnCompleteListener + } + val configModel = adapter.fromJson(jsonConfig) + val features = configModel?.toFeatures(ConfigType.Remote) ?: mutableMapOf() + val configValues = configModel?.toConfigValues() ?: mutableMapOf() + onComplete(Config(features, configValues)) + } else { + onComplete(emptyConfig) + } + }.addOnFailureListener { + Timber.e(it) + onComplete(emptyConfig) + } + } } \ No newline at end of file From 369ea273c21a8563748207bdb639f7f6915ae7ab Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 16 Nov 2020 17:10:55 +0300 Subject: [PATCH 03/21] Updated on 2026-08-14 --- app/src/main/assets/dev_features.json | 6 +- .../java/com/tangem/tap/TapApplication.kt | 28 ++++++++ .../tap/common/redux/global/GlobalAction.kt | 2 + .../tap/common/redux/global/GlobalReducer.kt | 3 + .../tap/common/redux/global/GlobalState.kt | 2 + .../java/com/tangem/tap/domain/TopUpHelper.kt | 7 +- .../tangem/tap/domain/config/ConfigLoader.kt | 6 +- .../tangem/tap/domain/config/ConfigManager.kt | 69 +++++++++++++++++++ .../tangem/tap/domain/config/JsonModels.kt | 2 +- .../com/tangem/tap/domain/config/Models.kt | 12 +++- .../features/wallet/redux/WalletMiddleware.kt | 8 ++- .../network/coinmarketcap/CoinMarketCapApi.kt | 9 ++- .../coinmarketcap/CoinMarketCapService.kt | 10 ++- 13 files changed, 143 insertions(+), 21 deletions(-) create mode 100644 app/src/main/java/com/tangem/tap/domain/config/ConfigManager.kt diff --git a/app/src/main/assets/dev_features.json b/app/src/main/assets/dev_features.json index aa3fd4c598..ded87444cb 100644 --- a/app/src/main/assets/dev_features.json +++ b/app/src/main/assets/dev_features.json @@ -1,12 +1,12 @@ { "features": [ { - "name": "payIdCreationEnabled", - "value": false + "name": "payIdIsEnabled", + "value": true }, { "name": "usePayId", - "value": false + "value": true }, { "name": "showWelcomeMessageAtStart", diff --git a/app/src/main/java/com/tangem/tap/TapApplication.kt b/app/src/main/java/com/tangem/tap/TapApplication.kt index b19bfc730e..24b84bb0d6 100644 --- a/app/src/main/java/com/tangem/tap/TapApplication.kt +++ b/app/src/main/java/com/tangem/tap/TapApplication.kt @@ -1,10 +1,16 @@ package com.tangem.tap import android.app.Application +import com.google.firebase.ktx.Firebase +import com.google.firebase.remoteconfig.ktx.remoteConfig +import com.google.firebase.remoteconfig.ktx.remoteConfigSettings import com.tangem.tap.common.images.PicassoHelper import com.tangem.tap.common.redux.AppState import com.tangem.tap.common.redux.appReducer +import com.tangem.tap.common.redux.global.GlobalAction +import com.tangem.tap.domain.config.* import com.tangem.tap.network.NetworkConnectivity +import com.tangem.tap.network.createMoshi import com.tangem.tap.persistence.PreferencesStorage import com.tangem.wallet.BuildConfig import org.rekotlin.Store @@ -20,11 +26,33 @@ lateinit var preferencesStorage: PreferencesStorage class TapApplication : Application() { override fun onCreate() { super.onCreate() + if (BuildConfig.DEBUG) { Timber.plant(Timber.DebugTree()) + Firebase.remoteConfig.setConfigSettingsAsync(remoteConfigSettings { + this.minimumFetchIntervalInSeconds = 60 + }) + } else { + Firebase.remoteConfig.setConfigSettingsAsync(remoteConfigSettings { + this.minimumFetchIntervalInSeconds = 3600 + }) } + NetworkConnectivity.createInstance(store, this) preferencesStorage = PreferencesStorage(this) PicassoHelper.initPicassoWithCaching(this) + + loadConfigs() + } + + + private fun loadConfigs() { + val moshiAdapter = createMoshi().adapter(ConfigModel::class.java) + val nameResolver = ConfigNameResolver.get() + + val localLoader = LocalLoader(this, nameResolver, moshiAdapter) + val remoteLoader = RemoteLoader(nameResolver, moshiAdapter) + val configManager = ConfigManager(localLoader, remoteLoader) + configManager.load { store.dispatch(GlobalAction.SetConfigManager(configManager)) } } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalAction.kt b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalAction.kt index c0e641bffe..9fb73bdfcb 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalAction.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalAction.kt @@ -1,5 +1,6 @@ package com.tangem.tap.common.redux.global +import com.tangem.tap.domain.config.ConfigManager import com.tangem.tap.domain.tasks.ScanNoteResponse import org.rekotlin.Action import java.math.BigDecimal @@ -15,4 +16,5 @@ sealed class GlobalAction : Action { data class Success(val appCurrency: FiatCurrencyName) : GlobalAction() } data class UpdateWalletSignedHashes(val walletSignedHashes: Int?) : GlobalAction() + data class SetConfigManager(val configManager: ConfigManager) : GlobalAction() } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalReducer.kt b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalReducer.kt index 66fbb80140..2b27751177 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalReducer.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalReducer.kt @@ -33,6 +33,9 @@ fun globalReducer(action: Action, state: AppState): GlobalState { globalState } } + is GlobalAction.SetConfigManager -> { + globalState.copy(configManager = action.configManager) + } else -> globalState } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalState.kt b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalState.kt index 9da6906d9c..f9e05cdeac 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalState.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalState.kt @@ -4,6 +4,7 @@ import com.tangem.commands.common.network.TangemService import com.tangem.tap.common.entities.TapCurrency.Companion.DEFAULT_FIAT_CURRENCY import com.tangem.tap.domain.PayIdManager import com.tangem.tap.domain.TapWalletManager +import com.tangem.tap.domain.config.ConfigManager import com.tangem.tap.domain.tasks.ScanNoteResponse import com.tangem.tap.network.coinmarketcap.CoinMarketCapService import org.rekotlin.StateType @@ -16,6 +17,7 @@ data class GlobalState( val coinMarketCapService: CoinMarketCapService = CoinMarketCapService(), val tangemService: TangemService = TangemService(), val conversionRates: ConversionRates = ConversionRates(emptyMap()), + val configManager: ConfigManager? = null, val appCurrency: FiatCurrencyName = DEFAULT_FIAT_CURRENCY ) : StateType diff --git a/app/src/main/java/com/tangem/tap/domain/TopUpHelper.kt b/app/src/main/java/com/tangem/tap/domain/TopUpHelper.kt index 6f715de06b..67d07b20d0 100644 --- a/app/src/main/java/com/tangem/tap/domain/TopUpHelper.kt +++ b/app/src/main/java/com/tangem/tap/domain/TopUpHelper.kt @@ -1,7 +1,6 @@ package com.tangem.tap.domain import android.net.Uri -import com.tangem.tap.TapConfig import com.tangem.tap.common.redux.global.CryptoCurrencyName import org.spongycastle.util.encoders.Base64 import javax.crypto.Mac @@ -19,12 +18,12 @@ class TopUpHelper { private const val REDIRECT_URL_PATH = "&redirectUrl=" private const val SIGNATURE_PATH = "&signature=" - fun getUrl(cryptoCurrencyName: CryptoCurrencyName, walletAddress: String): String { - val originalQuery = API_KEY_PATH + TapConfig.moonPayApiKey.urlEncode() + + fun getUrl(cryptoCurrencyName: CryptoCurrencyName, walletAddress: String, apiKey: String, secretKey: String): String { + val originalQuery = API_KEY_PATH + apiKey.urlEncode() + CURRENCY_PATH + cryptoCurrencyName.urlEncode() + WALLET_ADDRESS_PATH + walletAddress.urlEncode() + REDIRECT_URL_PATH + REDIRECT_URL.urlEncode() - val signature = createSignature(originalQuery, TapConfig.moonPayApiSecretKey) + val signature = createSignature(originalQuery, secretKey) return BASE_URL + originalQuery + SIGNATURE_PATH + signature.urlEncode() } diff --git a/app/src/main/java/com/tangem/tap/domain/config/ConfigLoader.kt b/app/src/main/java/com/tangem/tap/domain/config/ConfigLoader.kt index a9d07377cd..3cc7d2aec7 100644 --- a/app/src/main/java/com/tangem/tap/domain/config/ConfigLoader.kt +++ b/app/src/main/java/com/tangem/tap/domain/config/ConfigLoader.kt @@ -11,7 +11,7 @@ import timber.log.Timber [REDACTED_AUTHOR] */ interface ConfigLoader { - suspend fun loadConfig(onComplete: (Config) -> Unit) + fun loadConfig(onComplete: (Config) -> Unit) } @@ -47,7 +47,7 @@ class LocalLoader( private val adapter: JsonAdapter ) : ConfigLoader { - override suspend fun loadConfig(onComplete: (Config) -> Unit) { + override fun loadConfig(onComplete: (Config) -> Unit) { val config = try { val jsonFeatures = readAssetAsString(nameResolver.getFeaturesName()) var configModel = adapter.fromJson(jsonFeatures) @@ -74,7 +74,7 @@ class RemoteLoader( private val adapter: JsonAdapter ) : ConfigLoader { - override suspend fun loadConfig(onComplete: (Config) -> Unit) { + override fun loadConfig(onComplete: (Config) -> Unit) { val emptyConfig = Config.empty() val remoteConfig = Firebase.remoteConfig remoteConfig.fetchAndActivate().addOnCompleteListener { diff --git a/app/src/main/java/com/tangem/tap/domain/config/ConfigManager.kt b/app/src/main/java/com/tangem/tap/domain/config/ConfigManager.kt new file mode 100644 index 0000000000..f064353cc6 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/domain/config/ConfigManager.kt @@ -0,0 +1,69 @@ +package com.tangem.tap.domain.config + +import com.tangem.tangem_sdk_new.ui.animation.VoidCallback + +/** +[REDACTED_AUTHOR] + */ +enum class ConfigType { + Local, Remote +} + +class Config( + val features: MutableMap, + val configValues: MutableMap +) { + companion object { + fun empty(): Config = Config(mutableMapOf(), mutableMapOf()) + } +} + +class ConfigManager( + private val localLoader: ConfigLoader, + private val remoteLoader: ConfigLoader +) { + private var localConfig: Config = Config.empty() + private var remoteConfig: Config = Config.empty() + + fun load(onComplete: VoidCallback? = null) { + localLoader.loadConfig { localConfig = it } + remoteLoader.loadConfig { + remoteConfig = it + onComplete?.invoke() + } + } + + fun featureIsActive(name: String): Boolean { + return getFeatureWithHighestPriority(name)?.isActive() ?: false + } + + fun getFeature(name: String, type: ConfigType? = null): Feature? { + return when (type) { + ConfigType.Local -> localConfig.features[name] + ConfigType.Remote -> remoteConfig.features[name] + else -> getFeatureWithHighestPriority(name) + } + } + + private fun getFeatureWithHighestPriority(name: String): Feature? { + // if a localFeature doesn't exist then a remoteFeature won't exist to + val localFeature = localConfig.features[name] ?: return null + + // if the localFeature has a condition, then it has higher priority than a remoteFeature + return if (localFeature.hasCondition()) { + localFeature + } else { + // if not then the remoteFeature has higher priority than the localFeature + // if the remoteFeature doesn't exist - used the localFeature + remoteConfig.features[name] ?: localFeature + } + } + + fun getConfigValue(name: String): ConfigurationValue? { + return remoteConfig.configValues[name] ?: localConfig.configValues[name] + } + + fun updateCondition(name: String, condition: Condition?) { + localConfig.features[name]?.updateCondition(condition) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/config/JsonModels.kt b/app/src/main/java/com/tangem/tap/domain/config/JsonModels.kt index 18e1e80766..7b70001f1a 100644 --- a/app/src/main/java/com/tangem/tap/domain/config/JsonModels.kt +++ b/app/src/main/java/com/tangem/tap/domain/config/JsonModels.kt @@ -16,7 +16,7 @@ class FeatureModel( class ConfigValueModel( override val name: String, - override val value: String? + override val value: String ) : BaseConfigModel class ConfigModel(val features: List?, val configValues: List?) diff --git a/app/src/main/java/com/tangem/tap/domain/config/Models.kt b/app/src/main/java/com/tangem/tap/domain/config/Models.kt index 07a3bf28bb..8f40b8d367 100644 --- a/app/src/main/java/com/tangem/tap/domain/config/Models.kt +++ b/app/src/main/java/com/tangem/tap/domain/config/Models.kt @@ -13,7 +13,9 @@ interface Feature { fun hasCondition(): Boolean companion object { - val payIdIsEnabled = "payIdIsEnabled" + const val usePayId = "usePayId" + const val payIdIsEnabled = "payIdIsEnabled" + const val useTopUp = "useTopUp" } } @@ -42,4 +44,10 @@ class AppFeature( } } -data class ConfigurationValue(val name: String, val value: String?) \ No newline at end of file +data class ConfigurationValue(val name: String, val value: String) { + companion object { + const val coinMarketCapKey = "coinMarketCapKey" + const val moonPayApiKey = "moonPayApiKey" + const val moonPayApiSecretKey = "moonPayApiSecretKey" + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt index 71d07e315d..1f0b4769ee 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt @@ -19,6 +19,7 @@ import com.tangem.tap.common.redux.navigation.NavigationAction import com.tangem.tap.domain.PayIdManager import com.tangem.tap.domain.TapError import com.tangem.tap.domain.TopUpHelper +import com.tangem.tap.domain.config.ConfigurationValue import com.tangem.tap.domain.extensions.toSendableAmounts import com.tangem.tap.features.send.redux.PrepareSendScreen import com.tangem.tap.features.wallet.models.toPendingTransactions @@ -253,9 +254,14 @@ private class TopUpMiddleware { fun handle(action: WalletAction.TopUpAction) { when (action) { is WalletAction.TopUpAction.TopUp -> { + val configManager = store.state.globalState.configManager ?: return + val apiKey = configManager.getConfigValue(ConfigurationValue.moonPayApiKey)?.value ?: "" + val secretKey = configManager.getConfigValue(ConfigurationValue.moonPayApiSecretKey)?.value ?: "" val url = TopUpHelper.getUrl( store.state.walletState.currencyData.currencySymbol!!, - store.state.walletState.addressData!!.address + store.state.walletState.addressData!!.address, + apiKey, + secretKey ) Timber.d(url) store.dispatch(WalletAction.TopUpAction.Start(url, TopUpHelper.REDIRECT_URL)) diff --git a/app/src/main/java/com/tangem/tap/network/coinmarketcap/CoinMarketCapApi.kt b/app/src/main/java/com/tangem/tap/network/coinmarketcap/CoinMarketCapApi.kt index 47889ff06d..5d78846280 100644 --- a/app/src/main/java/com/tangem/tap/network/coinmarketcap/CoinMarketCapApi.kt +++ b/app/src/main/java/com/tangem/tap/network/coinmarketcap/CoinMarketCapApi.kt @@ -1,6 +1,5 @@ package com.tangem.tap.network.coinmarketcap -import com.tangem.tap.TapConfig import com.tangem.tap.network.createRetrofitInstance import okhttp3.Interceptor import okhttp3.Response @@ -23,20 +22,20 @@ interface CoinMarketCapApi { companion object { private const val baseUrl = "https://pro-api.coinmarketcap.com/" - fun create(): CoinMarketCapApi { + fun create(apiKey: String): CoinMarketCapApi { return createRetrofitInstance( baseUrl, - listOf(createCoinMarketRequestInterceptor()), + listOf(createCoinMarketRequestInterceptor(apiKey)), ).create(CoinMarketCapApi::class.java) } } } -private fun createCoinMarketRequestInterceptor(): Interceptor { +private fun createCoinMarketRequestInterceptor(apiKey: String): Interceptor { return object : Interceptor { override fun intercept(chain: Interceptor.Chain): Response { val requestBuilder = chain.request().newBuilder() - requestBuilder.addHeader("X-CMC_PRO_API_KEY", TapConfig.coinMarketCapKey) + requestBuilder.addHeader("X-CMC_PRO_API_KEY", apiKey) return chain.proceed(requestBuilder.build()) } } diff --git a/app/src/main/java/com/tangem/tap/network/coinmarketcap/CoinMarketCapService.kt b/app/src/main/java/com/tangem/tap/network/coinmarketcap/CoinMarketCapService.kt index 4dc7931623..b31b784929 100644 --- a/app/src/main/java/com/tangem/tap/network/coinmarketcap/CoinMarketCapService.kt +++ b/app/src/main/java/com/tangem/tap/network/coinmarketcap/CoinMarketCapService.kt @@ -3,12 +3,18 @@ package com.tangem.tap.network.coinmarketcap import com.tangem.commands.common.network.Result import com.tangem.commands.common.network.performRequest import com.tangem.tap.common.redux.global.FiatCurrencyName +import com.tangem.tap.domain.config.ConfigurationValue +import com.tangem.tap.store import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import java.math.BigDecimal -class CoinMarketCapService { - private val api: CoinMarketCapApi by lazy { CoinMarketCapApi.create() } +class CoinMarketCapService() { + private val api: CoinMarketCapApi by lazy { CoinMarketCapApi.create(getApiKey()) } + + private fun getApiKey(): String { + return store.state.globalState.configManager?.getConfigValue(ConfigurationValue.coinMarketCapKey)?.value!! + } suspend fun getRate( currency: String, fiatCurrency: FiatCurrencyName? = null From 4fa88e1959de70f79c5d9889b11d9bf59d0ce202 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 17 Nov 2020 10:30:29 +0300 Subject: [PATCH 04/21] Updated on 2026-08-14 --- app/src/main/assets/dev_config_values.json | 30 ++++---- app/src/main/assets/dev_features.json | 38 +++++---- .../java/com/tangem/tap/TapApplication.kt | 11 ++- app/src/main/java/com/tangem/tap/TapConfig.kt | 9 --- .../com/tangem/tap/domain/TapWalletManager.kt | 14 ++-- .../com/tangem/tap/domain/TapWorkarounds.kt | 17 ---- .../tangem/tap/domain/config/Conditions.kt | 27 ------- .../tangem/tap/domain/config/ConfigLoader.kt | 39 ++++++---- .../tangem/tap/domain/config/ConfigManager.kt | 77 ++++++++----------- .../tangem/tap/domain/config/JsonModels.kt | 20 ++--- .../com/tangem/tap/domain/config/Models.kt | 53 ------------- .../features/wallet/redux/WalletMiddleware.kt | 9 +-- .../coinmarketcap/CoinMarketCapService.kt | 3 +- 13 files changed, 110 insertions(+), 237 deletions(-) delete mode 100644 app/src/main/java/com/tangem/tap/TapConfig.kt delete mode 100644 app/src/main/java/com/tangem/tap/domain/TapWorkarounds.kt delete mode 100644 app/src/main/java/com/tangem/tap/domain/config/Conditions.kt delete mode 100644 app/src/main/java/com/tangem/tap/domain/config/Models.kt diff --git a/app/src/main/assets/dev_config_values.json b/app/src/main/assets/dev_config_values.json index 532adfd5c1..dec5d88c02 100644 --- a/app/src/main/assets/dev_config_values.json +++ b/app/src/main/assets/dev_config_values.json @@ -1,16 +1,14 @@ -{ - "configValues": [ - { - "name": "coinMarketCapKey", - "value": "f6622117-c043-47a0-8975-9d673ce484de" - }, - { - "name": "moonPayApiKey", - "value": "pk_test_kc90oYTANy7UQdBavDKGfL4K9l6VEPE" - }, - { - "name": "moonPayApiSecretKey", - "value": "sk_test_V8w4M19LbDjjYOt170s0tGuvXAgyEb1C" - } - ] -} \ No newline at end of file +[ + { + "name": "coinMarketCapKey", + "value": "f6622117-c043-47a0-8975-9d673ce484de" + }, + { + "name": "moonPayApiKey", + "value": "pk_test_kc90oYTANy7UQdBavDKGfL4K9l6VEPE" + }, + { + "name": "moonPayApiSecretKey", + "value": "sk_test_V8w4M19LbDjjYOt170s0tGuvXAgyEb1C" + } +] \ No newline at end of file diff --git a/app/src/main/assets/dev_features.json b/app/src/main/assets/dev_features.json index ded87444cb..ede98d72ef 100644 --- a/app/src/main/assets/dev_features.json +++ b/app/src/main/assets/dev_features.json @@ -1,20 +1,18 @@ -{ - "features": [ - { - "name": "payIdIsEnabled", - "value": true - }, - { - "name": "usePayId", - "value": true - }, - { - "name": "showWelcomeMessageAtStart", - "value": false - }, - { - "name": "useTopUp", - "value": false - } - ] -} \ No newline at end of file +[ + { + "name": "payIdIsEnabled", + "value": true + }, + { + "name": "usePayId", + "value": true + }, + { + "name": "showWelcomeMessageAtStart", + "value": false + }, + { + "name": "useTopUp", + "value": false + } +] \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/TapApplication.kt b/app/src/main/java/com/tangem/tap/TapApplication.kt index 24b84bb0d6..cea8c04e12 100644 --- a/app/src/main/java/com/tangem/tap/TapApplication.kt +++ b/app/src/main/java/com/tangem/tap/TapApplication.kt @@ -8,7 +8,10 @@ import com.tangem.tap.common.images.PicassoHelper import com.tangem.tap.common.redux.AppState import com.tangem.tap.common.redux.appReducer import com.tangem.tap.common.redux.global.GlobalAction -import com.tangem.tap.domain.config.* +import com.tangem.tap.domain.config.ConfigManager +import com.tangem.tap.domain.config.ConfigNameResolver +import com.tangem.tap.domain.config.LocalLoader +import com.tangem.tap.domain.config.RemoteLoader import com.tangem.tap.network.NetworkConnectivity import com.tangem.tap.network.createMoshi import com.tangem.tap.persistence.PreferencesStorage @@ -47,11 +50,11 @@ class TapApplication : Application() { private fun loadConfigs() { - val moshiAdapter = createMoshi().adapter(ConfigModel::class.java) + val moshi = createMoshi() val nameResolver = ConfigNameResolver.get() - val localLoader = LocalLoader(this, nameResolver, moshiAdapter) - val remoteLoader = RemoteLoader(nameResolver, moshiAdapter) + val localLoader = LocalLoader(this, nameResolver, moshi) + val remoteLoader = RemoteLoader(nameResolver, moshi) val configManager = ConfigManager(localLoader, remoteLoader) configManager.load { store.dispatch(GlobalAction.SetConfigManager(configManager)) } } diff --git a/app/src/main/java/com/tangem/tap/TapConfig.kt b/app/src/main/java/com/tangem/tap/TapConfig.kt deleted file mode 100644 index 9470f2935d..0000000000 --- a/app/src/main/java/com/tangem/tap/TapConfig.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.tangem.tap - -object TapConfig { - const val usePayId: Boolean = true - const val useTopUp: Boolean = true - const val coinMarketCapKey = "f6622117-c043-47a0-8975-9d673ce484de" - const val moonPayApiKey = "pk_test_kc90oYTANy7UQdBavDKGfL4K9l6VEPE" - const val moonPayApiSecretKey = "sk_test_V8w4M19LbDjjYOt170s0tGuvXAgyEb1C" -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt index 47ea2833f3..7f9eb116b1 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt @@ -5,7 +5,6 @@ import com.tangem.blockchain.common.WalletManager import com.tangem.commands.CardStatus import com.tangem.commands.common.network.Result import com.tangem.common.extensions.toHexString -import com.tangem.tap.TapConfig import com.tangem.tap.common.analytics.AnalyticsEvent import com.tangem.tap.common.analytics.FirebaseAnalyticsHandler import com.tangem.tap.common.redux.global.CryptoCurrencyName @@ -26,7 +25,6 @@ import java.math.BigDecimal class TapWalletManager { private val payIdManager = PayIdManager() private val coinMarketCapService = CoinMarketCapService() - private var tapWorkarounds: TapWorkarounds? = null suspend fun loadWalletData() { val walletManager = store.state.globalState.scanNoteResponse?.walletManager @@ -84,7 +82,7 @@ class TapWalletManager { if (addAnalyticsEvent) { FirebaseAnalyticsHandler.triggerEvent(AnalyticsEvent.CARD_IS_SCANNED, data.card) } - tapWorkarounds = TapWorkarounds(data.card) + store.state.globalState.configManager?.onCardScanned(data.card) withContext(Dispatchers.Main) { store.dispatch(WalletAction.ResetState) store.dispatch(GlobalAction.SaveScanNoteResponse(data)) @@ -101,9 +99,11 @@ class TapWalletManager { store.dispatch(WalletAction.LoadData.Failure(TapError.NoInternetConnection)) return@withContext } + val config = store.state.globalState.configManager?.config?: return@withContext + store.dispatch(WalletAction.LoadWallet( data.walletManager.wallet, data.verifyResponse?.artworkInfo?.id, - tapWorkarounds?.isStart2Coin != true && TapConfig.useTopUp + !config.isStart2Coin && config.useTopUp )) store.dispatch(WalletAction.LoadArtwork(data.card, artworkId)) store.dispatch(WalletAction.LoadFiatRate) @@ -150,8 +150,9 @@ class TapWalletManager { private suspend fun loadPayIdIfNeeded(): Result? { + val config = store.state.globalState.configManager?.config val scanNoteResponse = store.state.globalState.scanNoteResponse - if (!TapConfig.usePayId || + if (config?.usePayId == false || scanNoteResponse?.walletManager?.wallet?.blockchain?.isPayIdSupported() == false) { return null } @@ -169,7 +170,8 @@ class TapWalletManager { is Result.Success -> { val payId = result.data if (payId == null) { - if (tapWorkarounds?.isPayIdCreationEnabled() == false) { + val config = store.state.globalState.configManager?.config?: return@withContext + if (!config.payIdIsEnabled) { store.dispatch(WalletAction.DisablePayId) } else { store.dispatch(WalletAction.LoadPayId.NotCreated) diff --git a/app/src/main/java/com/tangem/tap/domain/TapWorkarounds.kt b/app/src/main/java/com/tangem/tap/domain/TapWorkarounds.kt deleted file mode 100644 index 9dc11ee062..0000000000 --- a/app/src/main/java/com/tangem/tap/domain/TapWorkarounds.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.tangem.tap.domain - -import com.tangem.commands.Card - -class TapWorkarounds(val card: Card) { - - val isStart2Coin: Boolean = card.cardData?.issuerName == START_2_COIN_ISSUER - - fun isPayIdCreationEnabled(): Boolean { - if (isStart2Coin) return false - return true - } - - companion object { - const val START_2_COIN_ISSUER = "start2coin" - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/config/Conditions.kt b/app/src/main/java/com/tangem/tap/domain/config/Conditions.kt deleted file mode 100644 index b684bdfbb3..0000000000 --- a/app/src/main/java/com/tangem/tap/domain/config/Conditions.kt +++ /dev/null @@ -1,27 +0,0 @@ -package com.tangem.tap.domain.config - -import com.tangem.commands.Card -import java.util.* - -/** -[REDACTED_AUTHOR] - */ -interface Condition { - fun isMet(): Boolean -} - -class CardIsStart2CoinCondition(private val card: Card?) : Condition { - - override fun isMet(): Boolean = card?.cardData?.issuerName?.toLowerCase(Locale.US) == "start2coin" -} - -class ConditionsFactory { - companion object { - fun create(name: String): Condition? { - return when (name) { - Feature.payIdIsEnabled -> CardIsStart2CoinCondition(null) - else -> null - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/config/ConfigLoader.kt b/app/src/main/java/com/tangem/tap/domain/config/ConfigLoader.kt index 3cc7d2aec7..d8ba2a3a96 100644 --- a/app/src/main/java/com/tangem/tap/domain/config/ConfigLoader.kt +++ b/app/src/main/java/com/tangem/tap/domain/config/ConfigLoader.kt @@ -4,6 +4,8 @@ import android.content.Context import com.google.firebase.ktx.Firebase import com.google.firebase.remoteconfig.ktx.remoteConfig import com.squareup.moshi.JsonAdapter +import com.squareup.moshi.Moshi +import com.squareup.moshi.Types import com.tangem.wallet.BuildConfig import timber.log.Timber @@ -11,7 +13,7 @@ import timber.log.Timber [REDACTED_AUTHOR] */ interface ConfigLoader { - fun loadConfig(onComplete: (Config) -> Unit) + fun loadConfig(onComplete: (ConfigModel) -> Unit) } @@ -41,25 +43,29 @@ class ConfigNameResolver { } } +class KeyValueModel(val name: String, value: T?) + class LocalLoader( private val context: Context, private val nameResolver: NameResolver, - private val adapter: JsonAdapter + private val moshi: Moshi ) : ConfigLoader { - override fun loadConfig(onComplete: (Config) -> Unit) { + override fun loadConfig(onComplete: (ConfigModel) -> Unit) { val config = try { - val jsonFeatures = readAssetAsString(nameResolver.getFeaturesName()) - var configModel = adapter.fromJson(jsonFeatures) - val features = configModel?.toFeatures(ConfigType.Local) ?: mutableMapOf() + val featureType = Types.newParameterizedType(List::class.java, FeatureModel::class.java) + val featureAdapter: JsonAdapter> = moshi.adapter(featureType) + val valuesType = Types.newParameterizedType(List::class.java, ConfigValueModel::class.java) + val valuesAdapter: JsonAdapter> = moshi.adapter(valuesType) + val jsonFeatures = readAssetAsString(nameResolver.getFeaturesName()) val jsonConfigValues = readAssetAsString(nameResolver.getConfigValuesName()) - configModel = adapter.fromJson(jsonConfigValues) - val configValues = configModel?.toConfigValues() ?: mutableMapOf() - Config(features, configValues) + + ConfigModel(featureAdapter.fromJson(jsonFeatures) ?: listOf(), + valuesAdapter.fromJson(jsonConfigValues) ?: listOf()) } catch (ex: Exception) { Timber.e(ex) - Config.empty() + ConfigModel.empty() } onComplete(config) } @@ -71,11 +77,11 @@ class LocalLoader( class RemoteLoader( private val nameResolver: NameResolver, - private val adapter: JsonAdapter + private val moshi: Moshi ) : ConfigLoader { - override fun loadConfig(onComplete: (Config) -> Unit) { - val emptyConfig = Config.empty() + override fun loadConfig(onComplete: (ConfigModel) -> Unit) { + val emptyConfig = ConfigModel.empty() val remoteConfig = Firebase.remoteConfig remoteConfig.fetchAndActivate().addOnCompleteListener { if (it.isSuccessful) { @@ -85,10 +91,9 @@ class RemoteLoader( onComplete(emptyConfig) return@addOnCompleteListener } - val configModel = adapter.fromJson(jsonConfig) - val features = configModel?.toFeatures(ConfigType.Remote) ?: mutableMapOf() - val configValues = configModel?.toConfigValues() ?: mutableMapOf() - onComplete(Config(features, configValues)) + val featureType = Types.newParameterizedType(List::class.java, FeatureModel::class.java) + val featureAdapter: JsonAdapter> = moshi.adapter(featureType) + onComplete(ConfigModel(featureAdapter.fromJson(jsonConfig) ?: listOf(), listOf())) } else { onComplete(emptyConfig) } diff --git a/app/src/main/java/com/tangem/tap/domain/config/ConfigManager.kt b/app/src/main/java/com/tangem/tap/domain/config/ConfigManager.kt index f064353cc6..a7faf046bf 100644 --- a/app/src/main/java/com/tangem/tap/domain/config/ConfigManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/config/ConfigManager.kt @@ -1,69 +1,56 @@ package com.tangem.tap.domain.config +import com.tangem.commands.Card import com.tangem.tangem_sdk_new.ui.animation.VoidCallback +import java.util.* /** [REDACTED_AUTHOR] */ -enum class ConfigType { - Local, Remote -} - -class Config( - val features: MutableMap, - val configValues: MutableMap -) { - companion object { - fun empty(): Config = Config(mutableMapOf(), mutableMapOf()) - } -} +data class ConfigState( + val coinMarketCapKey: String = "f6622117-c043-47a0-8975-9d673ce484de", + val moonPayApiKey: String = "pk_test_kc90oYTANy7UQdBavDKGfL4K9l6VEPE", + val moonPayApiSecretKey: String = "sk_test_V8w4M19LbDjjYOt170s0tGuvXAgyEb1C", + val payIdIsEnabled: Boolean = true, + val usePayId: Boolean = true, + val useTopUp: Boolean = true, + val isStart2Coin: Boolean = false +) class ConfigManager( private val localLoader: ConfigLoader, private val remoteLoader: ConfigLoader ) { - private var localConfig: Config = Config.empty() - private var remoteConfig: Config = Config.empty() + private val usePayId = "usePayId" + private val payIdIsEnabled = "payIdIsEnabled" + private val useTopUp = "useTopUp" + private val isStart2Coin = "isStart2Coin" + + var config: ConfigState = ConfigState() + private set fun load(onComplete: VoidCallback? = null) { - localLoader.loadConfig { localConfig = it } + localLoader.loadConfig { + it.features?.forEach { feature -> updateFeature(feature.name, feature.value) } + } remoteLoader.loadConfig { - remoteConfig = it + it.features?.forEach { feature -> updateFeature(feature.name, feature.value) } onComplete?.invoke() } } - fun featureIsActive(name: String): Boolean { - return getFeatureWithHighestPriority(name)?.isActive() ?: false + fun onCardScanned(card: Card) { + updateFeature(isStart2Coin, card.cardData?.issuerName?.toLowerCase(Locale.US) == "start2coin") } - fun getFeature(name: String, type: ConfigType? = null): Feature? { - return when (type) { - ConfigType.Local -> localConfig.features[name] - ConfigType.Remote -> remoteConfig.features[name] - else -> getFeatureWithHighestPriority(name) + private fun updateFeature(name: String, value: Boolean?) { + val newValue = value ?: return + + when (name) { + usePayId -> config = config.copy(usePayId = newValue) + payIdIsEnabled -> config = config.copy(payIdIsEnabled = newValue) + useTopUp -> config = config.copy(useTopUp = newValue) + isStart2Coin -> config = config.copy(isStart2Coin = newValue) } } - - private fun getFeatureWithHighestPriority(name: String): Feature? { - // if a localFeature doesn't exist then a remoteFeature won't exist to - val localFeature = localConfig.features[name] ?: return null - - // if the localFeature has a condition, then it has higher priority than a remoteFeature - return if (localFeature.hasCondition()) { - localFeature - } else { - // if not then the remoteFeature has higher priority than the localFeature - // if the remoteFeature doesn't exist - used the localFeature - remoteConfig.features[name] ?: localFeature - } - } - - fun getConfigValue(name: String): ConfigurationValue? { - return remoteConfig.configValues[name] ?: localConfig.configValues[name] - } - - fun updateCondition(name: String, condition: Condition?) { - localConfig.features[name]?.updateCondition(condition) - } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/config/JsonModels.kt b/app/src/main/java/com/tangem/tap/domain/config/JsonModels.kt index 7b70001f1a..be99fff956 100644 --- a/app/src/main/java/com/tangem/tap/domain/config/JsonModels.kt +++ b/app/src/main/java/com/tangem/tap/domain/config/JsonModels.kt @@ -19,18 +19,8 @@ class ConfigValueModel( override val value: String ) : BaseConfigModel -class ConfigModel(val features: List?, val configValues: List?) - -fun ConfigModel.toFeatures(type: ConfigType): MutableMap { - return features?.map { AppFeature(type, it, ConditionsFactory.create(it.name)) } - ?.associateBy { it.name } - ?.toMutableMap() - ?: mutableMapOf() -} - -fun ConfigModel.toConfigValues(): MutableMap { - return configValues?.map { ConfigurationValue(it.name, it.value) } - ?.associateBy { it.name } - ?.toMutableMap() ?: mutableMapOf() -} - +class ConfigModel(val features: List?, val configValues: List?) { + companion object { + fun empty(): ConfigModel = ConfigModel(listOf(), listOf()) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/config/Models.kt b/app/src/main/java/com/tangem/tap/domain/config/Models.kt deleted file mode 100644 index 8f40b8d367..0000000000 --- a/app/src/main/java/com/tangem/tap/domain/config/Models.kt +++ /dev/null @@ -1,53 +0,0 @@ -package com.tangem.tap.domain.config - -/** -[REDACTED_AUTHOR] - */ - -interface Feature { - val name: String - val type: ConfigType - fun isActive(): Boolean - fun reset() - fun updateCondition(condition: Condition?) - fun hasCondition(): Boolean - - companion object { - const val usePayId = "usePayId" - const val payIdIsEnabled = "payIdIsEnabled" - const val useTopUp = "useTopUp" - } -} - -class AppFeature( - override val type: ConfigType, - private val featureModel: FeatureModel, - private var condition: Condition? -) : Feature { - override val name: String = featureModel.name - - override fun isActive(): Boolean { - return if (condition == null) featureModel.value ?: false - else condition!!.isMet() - } - - override fun reset() { - condition = null - } - - override fun updateCondition(condition: Condition?) { - if (type == ConfigType.Local) this.condition = condition - } - - override fun hasCondition(): Boolean { - return condition != null - } -} - -data class ConfigurationValue(val name: String, val value: String) { - companion object { - const val coinMarketCapKey = "coinMarketCapKey" - const val moonPayApiKey = "moonPayApiKey" - const val moonPayApiSecretKey = "moonPayApiSecretKey" - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt index 1f0b4769ee..3b8e7a3fb5 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt @@ -19,7 +19,6 @@ import com.tangem.tap.common.redux.navigation.NavigationAction import com.tangem.tap.domain.PayIdManager import com.tangem.tap.domain.TapError import com.tangem.tap.domain.TopUpHelper -import com.tangem.tap.domain.config.ConfigurationValue import com.tangem.tap.domain.extensions.toSendableAmounts import com.tangem.tap.features.send.redux.PrepareSendScreen import com.tangem.tap.features.wallet.models.toPendingTransactions @@ -254,14 +253,12 @@ private class TopUpMiddleware { fun handle(action: WalletAction.TopUpAction) { when (action) { is WalletAction.TopUpAction.TopUp -> { - val configManager = store.state.globalState.configManager ?: return - val apiKey = configManager.getConfigValue(ConfigurationValue.moonPayApiKey)?.value ?: "" - val secretKey = configManager.getConfigValue(ConfigurationValue.moonPayApiSecretKey)?.value ?: "" + val config = store.state.globalState.configManager?.config ?: return val url = TopUpHelper.getUrl( store.state.walletState.currencyData.currencySymbol!!, store.state.walletState.addressData!!.address, - apiKey, - secretKey + config.moonPayApiKey, + config.moonPayApiSecretKey ) Timber.d(url) store.dispatch(WalletAction.TopUpAction.Start(url, TopUpHelper.REDIRECT_URL)) diff --git a/app/src/main/java/com/tangem/tap/network/coinmarketcap/CoinMarketCapService.kt b/app/src/main/java/com/tangem/tap/network/coinmarketcap/CoinMarketCapService.kt index b31b784929..fffc439820 100644 --- a/app/src/main/java/com/tangem/tap/network/coinmarketcap/CoinMarketCapService.kt +++ b/app/src/main/java/com/tangem/tap/network/coinmarketcap/CoinMarketCapService.kt @@ -3,7 +3,6 @@ package com.tangem.tap.network.coinmarketcap import com.tangem.commands.common.network.Result import com.tangem.commands.common.network.performRequest import com.tangem.tap.common.redux.global.FiatCurrencyName -import com.tangem.tap.domain.config.ConfigurationValue import com.tangem.tap.store import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext @@ -13,7 +12,7 @@ class CoinMarketCapService() { private val api: CoinMarketCapApi by lazy { CoinMarketCapApi.create(getApiKey()) } private fun getApiKey(): String { - return store.state.globalState.configManager?.getConfigValue(ConfigurationValue.coinMarketCapKey)?.value!! + return store.state.globalState.configManager?.config?.coinMarketCapKey ?: "" } suspend fun getRate( From 8a5528d3f5b3980df8ca3bdfef463b3a233c447a Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 17 Nov 2020 10:38:41 +0300 Subject: [PATCH 05/21] Updated on 2026-08-14 --- app/src/main/assets/dev_features.json | 4 ---- app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt | 2 +- .../main/java/com/tangem/tap/domain/config/ConfigManager.kt | 2 +- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/app/src/main/assets/dev_features.json b/app/src/main/assets/dev_features.json index ede98d72ef..450d65ba07 100644 --- a/app/src/main/assets/dev_features.json +++ b/app/src/main/assets/dev_features.json @@ -7,10 +7,6 @@ "name": "usePayId", "value": true }, - { - "name": "showWelcomeMessageAtStart", - "value": false - }, { "name": "useTopUp", "value": false diff --git a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt index 9b3c5fb814..a6ad3b9777 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt @@ -170,7 +170,7 @@ class TapWalletManager { is Result.Success -> { val config = store.state.globalState.configManager?.config?: return@withContext val payId = result.data - if (!config.isPayIdEnabled) { + if (!config.payIdIsEnabled) { store.dispatch(WalletAction.DisablePayId) return@withContext } diff --git a/app/src/main/java/com/tangem/tap/domain/config/ConfigManager.kt b/app/src/main/java/com/tangem/tap/domain/config/ConfigManager.kt index a7faf046bf..cf29c7e31f 100644 --- a/app/src/main/java/com/tangem/tap/domain/config/ConfigManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/config/ConfigManager.kt @@ -13,7 +13,7 @@ data class ConfigState( val moonPayApiSecretKey: String = "sk_test_V8w4M19LbDjjYOt170s0tGuvXAgyEb1C", val payIdIsEnabled: Boolean = true, val usePayId: Boolean = true, - val useTopUp: Boolean = true, + val useTopUp: Boolean = false, val isStart2Coin: Boolean = false ) From da2d9a8f93b4f1ec1bbc0907a156d748dcb69593 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 17 Nov 2020 10:42:25 +0300 Subject: [PATCH 06/21] Updated on 2026-08-14 --- app/src/main/assets/prod_config_values.json | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 app/src/main/assets/prod_config_values.json diff --git a/app/src/main/assets/prod_config_values.json b/app/src/main/assets/prod_config_values.json new file mode 100644 index 0000000000..dec5d88c02 --- /dev/null +++ b/app/src/main/assets/prod_config_values.json @@ -0,0 +1,14 @@ +[ + { + "name": "coinMarketCapKey", + "value": "f6622117-c043-47a0-8975-9d673ce484de" + }, + { + "name": "moonPayApiKey", + "value": "pk_test_kc90oYTANy7UQdBavDKGfL4K9l6VEPE" + }, + { + "name": "moonPayApiSecretKey", + "value": "sk_test_V8w4M19LbDjjYOt170s0tGuvXAgyEb1C" + } +] \ No newline at end of file From ee6f684780de49d16a7ebca7c70e2c0370379c65 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 17 Nov 2020 10:42:53 +0300 Subject: [PATCH 07/21] Updated on 2026-08-14 --- app/src/main/assets/prod_config_values.json | 14 -------------- app/src/main/assets/prod_features.json | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 14 deletions(-) delete mode 100644 app/src/main/assets/prod_config_values.json create mode 100644 app/src/main/assets/prod_features.json diff --git a/app/src/main/assets/prod_config_values.json b/app/src/main/assets/prod_config_values.json deleted file mode 100644 index dec5d88c02..0000000000 --- a/app/src/main/assets/prod_config_values.json +++ /dev/null @@ -1,14 +0,0 @@ -[ - { - "name": "coinMarketCapKey", - "value": "f6622117-c043-47a0-8975-9d673ce484de" - }, - { - "name": "moonPayApiKey", - "value": "pk_test_kc90oYTANy7UQdBavDKGfL4K9l6VEPE" - }, - { - "name": "moonPayApiSecretKey", - "value": "sk_test_V8w4M19LbDjjYOt170s0tGuvXAgyEb1C" - } -] \ No newline at end of file diff --git a/app/src/main/assets/prod_features.json b/app/src/main/assets/prod_features.json new file mode 100644 index 0000000000..450d65ba07 --- /dev/null +++ b/app/src/main/assets/prod_features.json @@ -0,0 +1,14 @@ +[ + { + "name": "payIdIsEnabled", + "value": true + }, + { + "name": "usePayId", + "value": true + }, + { + "name": "useTopUp", + "value": false + } +] \ No newline at end of file From 2ea7bbdb776b09b584f576984324ceb079a6173a Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 17 Nov 2020 10:54:38 +0300 Subject: [PATCH 08/21] Updated on 2026-08-14 --- .../tangem/tap/domain/config/ConfigManager.kt | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/domain/config/ConfigManager.kt b/app/src/main/java/com/tangem/tap/domain/config/ConfigManager.kt index cf29c7e31f..37fe46cc58 100644 --- a/app/src/main/java/com/tangem/tap/domain/config/ConfigManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/config/ConfigManager.kt @@ -25,13 +25,17 @@ class ConfigManager( private val payIdIsEnabled = "payIdIsEnabled" private val useTopUp = "useTopUp" private val isStart2Coin = "isStart2Coin" + private val coinMarketCapKey = "coinMarketCapKey" + private val moonPayApiKey = "moonPayApiKey" + private val moonPayApiSecretKey = "moonPayApiSecretKey" var config: ConfigState = ConfigState() private set fun load(onComplete: VoidCallback? = null) { - localLoader.loadConfig { - it.features?.forEach { feature -> updateFeature(feature.name, feature.value) } + localLoader.loadConfig {config -> + config.features?.forEach { updateFeature(it.name, it.value) } + config.configValues?.forEach { updateKeys(it.name, it.value) } } remoteLoader.loadConfig { it.features?.forEach { feature -> updateFeature(feature.name, feature.value) } @@ -53,4 +57,12 @@ class ConfigManager( isStart2Coin -> config = config.copy(isStart2Coin = newValue) } } + + private fun updateKeys(name: String, value: String) { + when (name) { + coinMarketCapKey -> config = config.copy(coinMarketCapKey = value) + moonPayApiKey -> config = config.copy(moonPayApiKey = value) + moonPayApiSecretKey -> config = config.copy(moonPayApiSecretKey = value) + } + } } \ No newline at end of file From cca12971eeabe9d3dc4f327b84b2ed7fe5b7e98a Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 17 Nov 2020 22:01:20 +0300 Subject: [PATCH 09/21] Updated on 2026-08-14 --- app/build.gradle | 4 +- app/src/main/assets/dev_config_values.json | 14 ---- app/src/main/assets/dev_features.json | 14 ---- app/src/main/assets/features_dev.json | 10 +++ app/src/main/assets/features_prod.json | 10 +++ app/src/main/assets/prod_features.json | 14 ---- .../java/com/tangem/tap/TapApplication.kt | 7 +- .../com/tangem/tap/domain/TapWalletManager.kt | 25 ++++-- .../com/tangem/tap/domain/TapWorkarounds.kt | 15 ++++ .../tangem/tap/domain/config/ConfigLoader.kt | 38 ++------- .../tangem/tap/domain/config/ConfigManager.kt | 84 ++++++++++++------- .../tangem/tap/domain/config/JsonModels.kt | 2 +- 12 files changed, 117 insertions(+), 120 deletions(-) delete mode 100644 app/src/main/assets/dev_config_values.json delete mode 100644 app/src/main/assets/dev_features.json create mode 100644 app/src/main/assets/features_dev.json create mode 100644 app/src/main/assets/features_prod.json delete mode 100644 app/src/main/assets/prod_features.json diff --git a/app/build.gradle b/app/build.gradle index 583846af6b..6598828e88 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -3,7 +3,6 @@ apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-kapt' apply plugin: 'com.google.firebase.crashlytics' -//apply plugin: 'com.google.firebase.firebase-perf' apply plugin: 'com.google.gms.google-services' android { @@ -25,6 +24,7 @@ android { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' signingConfig signingConfigs.debug + buildConfigField 'String', 'CONFIG_ENVIRONMENT', '\"prod\"' } debug { debuggable true @@ -34,11 +34,13 @@ android { firebaseCrashlytics { mappingFileUploadEnabled false } + buildConfigField 'String', 'CONFIG_ENVIRONMENT', '\"dev\"' } debug_beta { initWith debug versionNameSuffix "-beta" applicationIdSuffix ".debug" + buildConfigField 'String', 'CONFIG_ENVIRONMENT', '\"dev\"' } } kotlinOptions { diff --git a/app/src/main/assets/dev_config_values.json b/app/src/main/assets/dev_config_values.json deleted file mode 100644 index dec5d88c02..0000000000 --- a/app/src/main/assets/dev_config_values.json +++ /dev/null @@ -1,14 +0,0 @@ -[ - { - "name": "coinMarketCapKey", - "value": "f6622117-c043-47a0-8975-9d673ce484de" - }, - { - "name": "moonPayApiKey", - "value": "pk_test_kc90oYTANy7UQdBavDKGfL4K9l6VEPE" - }, - { - "name": "moonPayApiSecretKey", - "value": "sk_test_V8w4M19LbDjjYOt170s0tGuvXAgyEb1C" - } -] \ No newline at end of file diff --git a/app/src/main/assets/dev_features.json b/app/src/main/assets/dev_features.json deleted file mode 100644 index 450d65ba07..0000000000 --- a/app/src/main/assets/dev_features.json +++ /dev/null @@ -1,14 +0,0 @@ -[ - { - "name": "payIdIsEnabled", - "value": true - }, - { - "name": "usePayId", - "value": true - }, - { - "name": "useTopUp", - "value": false - } -] \ No newline at end of file diff --git a/app/src/main/assets/features_dev.json b/app/src/main/assets/features_dev.json new file mode 100644 index 0000000000..e932f5787b --- /dev/null +++ b/app/src/main/assets/features_dev.json @@ -0,0 +1,10 @@ +[ + { + "name": "isPayIdCreationEnabled", + "value": false + }, + { + "name": "isTopUpEnabled", + "value": false + } +] \ No newline at end of file diff --git a/app/src/main/assets/features_prod.json b/app/src/main/assets/features_prod.json new file mode 100644 index 0000000000..e932f5787b --- /dev/null +++ b/app/src/main/assets/features_prod.json @@ -0,0 +1,10 @@ +[ + { + "name": "isPayIdCreationEnabled", + "value": false + }, + { + "name": "isTopUpEnabled", + "value": false + } +] \ No newline at end of file diff --git a/app/src/main/assets/prod_features.json b/app/src/main/assets/prod_features.json deleted file mode 100644 index 450d65ba07..0000000000 --- a/app/src/main/assets/prod_features.json +++ /dev/null @@ -1,14 +0,0 @@ -[ - { - "name": "payIdIsEnabled", - "value": true - }, - { - "name": "usePayId", - "value": true - }, - { - "name": "useTopUp", - "value": false - } -] \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/TapApplication.kt b/app/src/main/java/com/tangem/tap/TapApplication.kt index cea8c04e12..5e43828af0 100644 --- a/app/src/main/java/com/tangem/tap/TapApplication.kt +++ b/app/src/main/java/com/tangem/tap/TapApplication.kt @@ -9,7 +9,6 @@ import com.tangem.tap.common.redux.AppState import com.tangem.tap.common.redux.appReducer import com.tangem.tap.common.redux.global.GlobalAction import com.tangem.tap.domain.config.ConfigManager -import com.tangem.tap.domain.config.ConfigNameResolver import com.tangem.tap.domain.config.LocalLoader import com.tangem.tap.domain.config.RemoteLoader import com.tangem.tap.network.NetworkConnectivity @@ -51,10 +50,8 @@ class TapApplication : Application() { private fun loadConfigs() { val moshi = createMoshi() - val nameResolver = ConfigNameResolver.get() - - val localLoader = LocalLoader(this, nameResolver, moshi) - val remoteLoader = RemoteLoader(nameResolver, moshi) + val localLoader = LocalLoader(this, moshi) + val remoteLoader = RemoteLoader(moshi) val configManager = ConfigManager(localLoader, remoteLoader) configManager.load { store.dispatch(GlobalAction.SetConfigManager(configManager)) } } diff --git a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt index a6ad3b9777..8b92e9604e 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt @@ -1,5 +1,6 @@ package com.tangem.tap.domain +import TapWorkarounds import com.tangem.blockchain.common.Wallet import com.tangem.blockchain.common.WalletManager import com.tangem.commands.CardStatus @@ -10,6 +11,7 @@ import com.tangem.tap.common.analytics.FirebaseAnalyticsHandler import com.tangem.tap.common.redux.global.CryptoCurrencyName import com.tangem.tap.common.redux.global.FiatCurrencyName import com.tangem.tap.common.redux.global.GlobalAction +import com.tangem.tap.domain.config.ConfigManager import com.tangem.tap.domain.extensions.amountToCreateAccount import com.tangem.tap.domain.extensions.isNoAccountError import com.tangem.tap.domain.tasks.ScanNoteResponse @@ -25,6 +27,7 @@ import java.math.BigDecimal class TapWalletManager { private val payIdManager = PayIdManager() private val coinMarketCapService = CoinMarketCapService() + private var tapWorkarounds: TapWorkarounds? = null suspend fun loadWalletData() { val walletManager = store.state.globalState.scanNoteResponse?.walletManager @@ -82,7 +85,12 @@ class TapWalletManager { if (addAnalyticsEvent) { FirebaseAnalyticsHandler.triggerEvent(AnalyticsEvent.CARD_IS_SCANNED, data.card) } - store.state.globalState.configManager?.onCardScanned(data.card) + tapWorkarounds = TapWorkarounds(data.card) + if (tapWorkarounds!!.isStart2Coin) { + store.state.globalState.configManager?.turnOf(ConfigManager.isPayIdCreationEnabled) + } else { + store.state.globalState.configManager?.resetToDefault(ConfigManager.isPayIdCreationEnabled) + } withContext(Dispatchers.Main) { store.dispatch(WalletAction.ResetState) store.dispatch(GlobalAction.SaveScanNoteResponse(data)) @@ -99,11 +107,11 @@ class TapWalletManager { store.dispatch(WalletAction.LoadData.Failure(TapError.NoInternetConnection)) return@withContext } - val config = store.state.globalState.configManager?.config?: return@withContext + val config = store.state.globalState.configManager?.config ?: return@withContext store.dispatch(WalletAction.LoadWallet( data.walletManager.wallet, data.verifyResponse?.artworkInfo?.id, - !config.isStart2Coin && config.useTopUp + tapWorkarounds?.isStart2Coin == false && config.isTopUpEnabled )) store.dispatch(WalletAction.LoadArtwork(data.card, artworkId)) store.dispatch(WalletAction.LoadFiatRate) @@ -150,10 +158,9 @@ class TapWalletManager { private suspend fun loadPayIdIfNeeded(): Result? { - val config = store.state.globalState.configManager?.config val scanNoteResponse = store.state.globalState.scanNoteResponse - if (config?.usePayId == false || - scanNoteResponse?.walletManager?.wallet?.blockchain?.isPayIdSupported() == false) { + if (store.state.globalState.configManager?.config?.isPayIdCreationEnabled == false + || scanNoteResponse?.walletManager?.wallet?.blockchain?.isPayIdSupported() == false) { return null } val cardId = scanNoteResponse?.card?.cardId @@ -168,12 +175,12 @@ class TapWalletManager { withContext(Dispatchers.Main) { when (result) { is Result.Success -> { - val config = store.state.globalState.configManager?.config?: return@withContext - val payId = result.data - if (!config.payIdIsEnabled) { + val config = store.state.globalState.configManager?.config + if (config?.isPayIdCreationEnabled == false) { store.dispatch(WalletAction.DisablePayId) return@withContext } + val payId = result.data if (payId == null) { store.dispatch(WalletAction.LoadPayId.NotCreated) } else { diff --git a/app/src/main/java/com/tangem/tap/domain/TapWorkarounds.kt b/app/src/main/java/com/tangem/tap/domain/TapWorkarounds.kt index e69de29bb2..0438f0d810 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapWorkarounds.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapWorkarounds.kt @@ -0,0 +1,15 @@ +import com.tangem.commands.Card + +class TapWorkarounds(val card: Card) { + + val isStart2Coin: Boolean = card.cardData?.issuerName == START_2_COIN_ISSUER + + fun isPayisPayIdEnabled(): Boolean { + if (isStart2Coin) return false + return true + } + + companion object { + const val START_2_COIN_ISSUER = "start2coin" + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/config/ConfigLoader.kt b/app/src/main/java/com/tangem/tap/domain/config/ConfigLoader.kt index d8ba2a3a96..60bb343e02 100644 --- a/app/src/main/java/com/tangem/tap/domain/config/ConfigLoader.kt +++ b/app/src/main/java/com/tangem/tap/domain/config/ConfigLoader.kt @@ -1,6 +1,7 @@ package com.tangem.tap.domain.config import android.content.Context +import com.google.firebase.crashlytics.FirebaseCrashlytics import com.google.firebase.ktx.Firebase import com.google.firebase.remoteconfig.ktx.remoteConfig import com.squareup.moshi.JsonAdapter @@ -14,40 +15,16 @@ import timber.log.Timber */ interface ConfigLoader { fun loadConfig(onComplete: (ConfigModel) -> Unit) -} - -interface NameResolver { - fun getFeaturesName(): String - fun getConfigValuesName(): String -} - -class ConfigNameResolver { companion object { - fun get(): NameResolver = if (BuildConfig.DEBUG) dev() else prod() - - private fun dev(): NameResolver { - return object : NameResolver { - override fun getFeaturesName(): String = "dev_features" - override fun getConfigValuesName(): String = "dev_config_values" - } - } - - private fun prod(): NameResolver { - return object : NameResolver { - override fun getFeaturesName(): String = "prod_features" - override fun getConfigValuesName(): String = "prod_config_values" - - } - } + const val featuresName = "features_${BuildConfig.CONFIG_ENVIRONMENT}" + const val configValuesName = "config_${BuildConfig.CONFIG_ENVIRONMENT}" } } -class KeyValueModel(val name: String, value: T?) class LocalLoader( private val context: Context, - private val nameResolver: NameResolver, private val moshi: Moshi ) : ConfigLoader { @@ -58,8 +35,8 @@ class LocalLoader( val valuesType = Types.newParameterizedType(List::class.java, ConfigValueModel::class.java) val valuesAdapter: JsonAdapter> = moshi.adapter(valuesType) - val jsonFeatures = readAssetAsString(nameResolver.getFeaturesName()) - val jsonConfigValues = readAssetAsString(nameResolver.getConfigValuesName()) + val jsonFeatures = readAssetAsString(ConfigLoader.featuresName) + val jsonConfigValues = readAssetAsString(ConfigLoader.configValuesName) ConfigModel(featureAdapter.fromJson(jsonFeatures) ?: listOf(), valuesAdapter.fromJson(jsonConfigValues) ?: listOf()) @@ -76,7 +53,6 @@ class LocalLoader( } class RemoteLoader( - private val nameResolver: NameResolver, private val moshi: Moshi ) : ConfigLoader { @@ -85,7 +61,7 @@ class RemoteLoader( val remoteConfig = Firebase.remoteConfig remoteConfig.fetchAndActivate().addOnCompleteListener { if (it.isSuccessful) { - val config = remoteConfig.getValue(nameResolver.getFeaturesName()) + val config = remoteConfig.getValue(ConfigLoader.featuresName) val jsonConfig = config.asString() if (jsonConfig.isEmpty()) { onComplete(emptyConfig) @@ -98,7 +74,7 @@ class RemoteLoader( onComplete(emptyConfig) } }.addOnFailureListener { - Timber.e(it) + FirebaseCrashlytics.getInstance().recordException(it) onComplete(emptyConfig) } } diff --git a/app/src/main/java/com/tangem/tap/domain/config/ConfigManager.kt b/app/src/main/java/com/tangem/tap/domain/config/ConfigManager.kt index 37fe46cc58..b9b05b49fe 100644 --- a/app/src/main/java/com/tangem/tap/domain/config/ConfigManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/config/ConfigManager.kt @@ -1,68 +1,90 @@ package com.tangem.tap.domain.config -import com.tangem.commands.Card import com.tangem.tangem_sdk_new.ui.animation.VoidCallback -import java.util.* /** [REDACTED_AUTHOR] */ -data class ConfigState( +data class Config( val coinMarketCapKey: String = "f6622117-c043-47a0-8975-9d673ce484de", val moonPayApiKey: String = "pk_test_kc90oYTANy7UQdBavDKGfL4K9l6VEPE", val moonPayApiSecretKey: String = "sk_test_V8w4M19LbDjjYOt170s0tGuvXAgyEb1C", - val payIdIsEnabled: Boolean = true, - val usePayId: Boolean = true, - val useTopUp: Boolean = false, - val isStart2Coin: Boolean = false + val isPayIdCreationEnabled: Boolean = true, + val isTopUpEnabled: Boolean = false, ) class ConfigManager( private val localLoader: ConfigLoader, private val remoteLoader: ConfigLoader ) { - private val usePayId = "usePayId" - private val payIdIsEnabled = "payIdIsEnabled" - private val useTopUp = "useTopUp" - private val isStart2Coin = "isStart2Coin" - private val coinMarketCapKey = "coinMarketCapKey" - private val moonPayApiKey = "moonPayApiKey" - private val moonPayApiSecretKey = "moonPayApiSecretKey" - var config: ConfigState = ConfigState() + var config: Config = Config() private set + private var defaultConfig = Config() + fun load(onComplete: VoidCallback? = null) { - localLoader.loadConfig {config -> - config.features?.forEach { updateFeature(it.name, it.value) } - config.configValues?.forEach { updateKeys(it.name, it.value) } + localLoader.loadConfig { config -> + config.features?.forEach { setupFeature(it.name, it.value) } + config.configValues?.forEach { setupKey(it.name, it.value) } } - remoteLoader.loadConfig { - it.features?.forEach { feature -> updateFeature(feature.name, feature.value) } + remoteLoader.loadConfig { config -> + config.features?.forEach { setupFeature(it.name, it.value) } onComplete?.invoke() } } - fun onCardScanned(card: Card) { - updateFeature(isStart2Coin, card.cardData?.issuerName?.toLowerCase(Locale.US) == "start2coin") + fun turnOf(name: String) { + when (name) { + isPayIdCreationEnabled -> config = config.copy(isPayIdCreationEnabled = false) + isTopUpEnabled -> config = config.copy(isTopUpEnabled = false) + } } - private fun updateFeature(name: String, value: Boolean?) { + fun resetToDefault(name: String) { + when (name) { + isPayIdCreationEnabled -> config = config.copy(isPayIdCreationEnabled = defaultConfig.isPayIdCreationEnabled) + isTopUpEnabled -> config = config.copy(isTopUpEnabled = defaultConfig.isTopUpEnabled) + } + } + + private fun setupFeature(name: String, value: Boolean) { val newValue = value ?: return when (name) { - usePayId -> config = config.copy(usePayId = newValue) - payIdIsEnabled -> config = config.copy(payIdIsEnabled = newValue) - useTopUp -> config = config.copy(useTopUp = newValue) - isStart2Coin -> config = config.copy(isStart2Coin = newValue) + isPayIdCreationEnabled -> { + config = config.copy(isPayIdCreationEnabled = newValue) + defaultConfig = defaultConfig.copy(isPayIdCreationEnabled = newValue) + } + isTopUpEnabled -> { + config = config.copy(isTopUpEnabled = newValue) + defaultConfig = defaultConfig.copy(isTopUpEnabled = newValue) + } } } - private fun updateKeys(name: String, value: String) { + private fun setupKey(name: String, value: String) { when (name) { - coinMarketCapKey -> config = config.copy(coinMarketCapKey = value) - moonPayApiKey -> config = config.copy(moonPayApiKey = value) - moonPayApiSecretKey -> config = config.copy(moonPayApiSecretKey = value) + coinMarketCapKey -> { + config = config.copy(coinMarketCapKey = value) + defaultConfig = defaultConfig.copy(coinMarketCapKey = value) + } + moonPayApiKey -> { + config = config.copy(moonPayApiKey = value) + defaultConfig = defaultConfig.copy(moonPayApiKey = value) + } + moonPayApiSecretKey -> { + config = config.copy(moonPayApiSecretKey = value) + defaultConfig = defaultConfig.copy(moonPayApiSecretKey = value) + } } } + + companion object { + const val isPayIdCreationEnabled = "isPayIdCreationEnabled" + const val isTopUpEnabled = "useTopUp" + const val coinMarketCapKey = "coinMarketCapKey" + const val moonPayApiKey = "moonPayApiKey" + const val moonPayApiSecretKey = "moonPayApiSecretKey" + } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/config/JsonModels.kt b/app/src/main/java/com/tangem/tap/domain/config/JsonModels.kt index be99fff956..1b7272765b 100644 --- a/app/src/main/java/com/tangem/tap/domain/config/JsonModels.kt +++ b/app/src/main/java/com/tangem/tap/domain/config/JsonModels.kt @@ -11,7 +11,7 @@ interface BaseConfigModel { class FeatureModel( override val name: String, - override val value: Boolean? + override val value: Boolean ) : BaseConfigModel class ConfigValueModel( From 5a14ad24798cc737a52007deab0853b04407d0bd Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 17 Nov 2020 22:05:25 +0300 Subject: [PATCH 10/21] Updated on 2026-08-14 --- .../main/java/com/tangem/tap/domain/TapWorkarounds.kt | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/domain/TapWorkarounds.kt b/app/src/main/java/com/tangem/tap/domain/TapWorkarounds.kt index 0438f0d810..7ac2457aa0 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapWorkarounds.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapWorkarounds.kt @@ -1,13 +1,12 @@ +package com.tangem.tap.domain + import com.tangem.commands.Card +import java.util.* class TapWorkarounds(val card: Card) { - val isStart2Coin: Boolean = card.cardData?.issuerName == START_2_COIN_ISSUER - - fun isPayisPayIdEnabled(): Boolean { - if (isStart2Coin) return false - return true - } + val isStart2Coin: Boolean = + card.cardData?.issuerName?.toLowerCase(Locale.US) == START_2_COIN_ISSUER companion object { const val START_2_COIN_ISSUER = "start2coin" From 0e5727eda0914c715accd25fd2a3b68c46c674e3 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 18 Nov 2020 10:05:30 +0300 Subject: [PATCH 11/21] Updated on 2026-08-14 --- app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt index 8b92e9604e..80b4bd5719 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt @@ -1,6 +1,5 @@ package com.tangem.tap.domain -import TapWorkarounds import com.tangem.blockchain.common.Wallet import com.tangem.blockchain.common.WalletManager import com.tangem.commands.CardStatus From 03372962fac06fdb2123b291cf3214c77b787921 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 18 Nov 2020 12:46:39 +0300 Subject: [PATCH 12/21] Updated on 2026-08-14 --- app/src/main/assets/features_dev.json | 6 +++--- app/src/main/assets/features_prod.json | 2 +- .../java/com/tangem/tap/domain/TapWalletManager.kt | 8 ++++---- .../com/tangem/tap/domain/config/ConfigManager.kt | 14 +++++++------- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/app/src/main/assets/features_dev.json b/app/src/main/assets/features_dev.json index e932f5787b..33cf6e331b 100644 --- a/app/src/main/assets/features_dev.json +++ b/app/src/main/assets/features_dev.json @@ -1,10 +1,10 @@ [ { - "name": "isPayIdCreationEnabled", - "value": false + "name": "isWalletPayIdEnabled", + "value": true }, { "name": "isTopUpEnabled", - "value": false + "value": true } ] \ No newline at end of file diff --git a/app/src/main/assets/features_prod.json b/app/src/main/assets/features_prod.json index e932f5787b..ede61eb088 100644 --- a/app/src/main/assets/features_prod.json +++ b/app/src/main/assets/features_prod.json @@ -1,6 +1,6 @@ [ { - "name": "isPayIdCreationEnabled", + "name": "isWalletPayIdEnabled", "value": false }, { diff --git a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt index 80b4bd5719..3713c72808 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt @@ -86,9 +86,9 @@ class TapWalletManager { } tapWorkarounds = TapWorkarounds(data.card) if (tapWorkarounds!!.isStart2Coin) { - store.state.globalState.configManager?.turnOf(ConfigManager.isPayIdCreationEnabled) + store.state.globalState.configManager?.turnOf(ConfigManager.isWalletPayIdEnabled) } else { - store.state.globalState.configManager?.resetToDefault(ConfigManager.isPayIdCreationEnabled) + store.state.globalState.configManager?.resetToDefault(ConfigManager.isWalletPayIdEnabled) } withContext(Dispatchers.Main) { store.dispatch(WalletAction.ResetState) @@ -158,7 +158,7 @@ class TapWalletManager { private suspend fun loadPayIdIfNeeded(): Result? { val scanNoteResponse = store.state.globalState.scanNoteResponse - if (store.state.globalState.configManager?.config?.isPayIdCreationEnabled == false + if (store.state.globalState.configManager?.config?.isWalletPayIdEnabled == false || scanNoteResponse?.walletManager?.wallet?.blockchain?.isPayIdSupported() == false) { return null } @@ -175,7 +175,7 @@ class TapWalletManager { when (result) { is Result.Success -> { val config = store.state.globalState.configManager?.config - if (config?.isPayIdCreationEnabled == false) { + if (config?.isWalletPayIdEnabled == false) { store.dispatch(WalletAction.DisablePayId) return@withContext } diff --git a/app/src/main/java/com/tangem/tap/domain/config/ConfigManager.kt b/app/src/main/java/com/tangem/tap/domain/config/ConfigManager.kt index b9b05b49fe..668339cd20 100644 --- a/app/src/main/java/com/tangem/tap/domain/config/ConfigManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/config/ConfigManager.kt @@ -9,7 +9,7 @@ data class Config( val coinMarketCapKey: String = "f6622117-c043-47a0-8975-9d673ce484de", val moonPayApiKey: String = "pk_test_kc90oYTANy7UQdBavDKGfL4K9l6VEPE", val moonPayApiSecretKey: String = "sk_test_V8w4M19LbDjjYOt170s0tGuvXAgyEb1C", - val isPayIdCreationEnabled: Boolean = true, + val isWalletPayIdEnabled: Boolean = true, val isTopUpEnabled: Boolean = false, ) @@ -36,14 +36,14 @@ class ConfigManager( fun turnOf(name: String) { when (name) { - isPayIdCreationEnabled -> config = config.copy(isPayIdCreationEnabled = false) + isWalletPayIdEnabled -> config = config.copy(isWalletPayIdEnabled = false) isTopUpEnabled -> config = config.copy(isTopUpEnabled = false) } } fun resetToDefault(name: String) { when (name) { - isPayIdCreationEnabled -> config = config.copy(isPayIdCreationEnabled = defaultConfig.isPayIdCreationEnabled) + isWalletPayIdEnabled -> config = config.copy(isWalletPayIdEnabled = defaultConfig.isWalletPayIdEnabled) isTopUpEnabled -> config = config.copy(isTopUpEnabled = defaultConfig.isTopUpEnabled) } } @@ -52,9 +52,9 @@ class ConfigManager( val newValue = value ?: return when (name) { - isPayIdCreationEnabled -> { - config = config.copy(isPayIdCreationEnabled = newValue) - defaultConfig = defaultConfig.copy(isPayIdCreationEnabled = newValue) + isWalletPayIdEnabled -> { + config = config.copy(isWalletPayIdEnabled = newValue) + defaultConfig = defaultConfig.copy(isWalletPayIdEnabled = newValue) } isTopUpEnabled -> { config = config.copy(isTopUpEnabled = newValue) @@ -81,7 +81,7 @@ class ConfigManager( } companion object { - const val isPayIdCreationEnabled = "isPayIdCreationEnabled" + const val isWalletPayIdEnabled = "isWalletPayIdEnabled" const val isTopUpEnabled = "useTopUp" const val coinMarketCapKey = "coinMarketCapKey" const val moonPayApiKey = "moonPayApiKey" From 5b775a2eb582c4a80dd11bbf13738db6d97dd693 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 18 Nov 2020 12:47:15 +0300 Subject: [PATCH 13/21] Updated on 2026-08-14 From 00b6a51430a8c0d326689d31af98f468e054119b Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 18 Nov 2020 13:25:33 +0300 Subject: [PATCH 14/21] Updated on 2026-08-14 From 8ef3ff57864feb7390702f92cb4e537f0d17a026 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 18 Nov 2020 13:30:43 +0300 Subject: [PATCH 15/21] Updated on 2026-08-14 From 1d6bac77dd2efa186bc1414b701723c6dd4ca3a0 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 18 Nov 2020 13:51:43 +0300 Subject: [PATCH 16/21] Updated on 2026-08-14 --- app/build.gradle | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 6598828e88..bec0e82735 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -3,7 +3,6 @@ apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-kapt' apply plugin: 'com.google.firebase.crashlytics' -apply plugin: 'com.google.gms.google-services' android { compileSdkVersion 29 @@ -108,4 +107,11 @@ dependencies { androidTestImplementation 'androidx.test.ext:junit:1.1.2' androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' +} + +apply plugin: 'com.google.gms.google-services' + +android.applicationVariants.all { variant -> + def googleTask = tasks.findByName("process${variant.name.capitalize()}GoogleServices") + googleTask.enabled = "release".equals(variant.name) } \ No newline at end of file From 7f7b87d3642e5c4d168e82d820ba2ee1377037a6 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 18 Nov 2020 15:56:30 +0300 Subject: [PATCH 17/21] Updated on 2026-08-14 --- app/build.gradle | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index bec0e82735..6dac91f10b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -3,6 +3,7 @@ apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-kapt' apply plugin: 'com.google.firebase.crashlytics' +apply plugin: 'com.google.gms.google-services' android { compileSdkVersion 29 @@ -39,7 +40,6 @@ android { initWith debug versionNameSuffix "-beta" applicationIdSuffix ".debug" - buildConfigField 'String', 'CONFIG_ENVIRONMENT', '\"dev\"' } } kotlinOptions { @@ -107,11 +107,4 @@ dependencies { androidTestImplementation 'androidx.test.ext:junit:1.1.2' androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' -} - -apply plugin: 'com.google.gms.google-services' - -android.applicationVariants.all { variant -> - def googleTask = tasks.findByName("process${variant.name.capitalize()}GoogleServices") - googleTask.enabled = "release".equals(variant.name) } \ No newline at end of file From e24cb82db918c74bb7441c4573f14b9b6fab5f95 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 18 Nov 2020 15:59:35 +0300 Subject: [PATCH 18/21] Updated on 2026-08-14 From bb20ae336082be9c0061db3c96aa136aad274deb Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 18 Nov 2020 16:02:54 +0300 Subject: [PATCH 19/21] Updated on 2026-08-14 From 770ff012f8e02ee3b8a6a78abdb10d8e9386cdf6 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 18 Nov 2020 18:32:20 +0300 Subject: [PATCH 20/21] Updated on 2026-08-14 --- .../main/java/com/tangem/tap/domain/TapWalletManager.kt | 8 ++++---- .../java/com/tangem/tap/domain/config/ConfigManager.kt | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt index 3713c72808..82d4d105bc 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt @@ -86,9 +86,11 @@ class TapWalletManager { } tapWorkarounds = TapWorkarounds(data.card) if (tapWorkarounds!!.isStart2Coin) { - store.state.globalState.configManager?.turnOf(ConfigManager.isWalletPayIdEnabled) + store.state.globalState.configManager?.turnOff(ConfigManager.isWalletPayIdEnabled) + store.state.globalState.configManager?.turnOff(ConfigManager.isTopUpEnabled) } else { store.state.globalState.configManager?.resetToDefault(ConfigManager.isWalletPayIdEnabled) + store.state.globalState.configManager?.resetToDefault(ConfigManager.isTopUpEnabled) } withContext(Dispatchers.Main) { store.dispatch(WalletAction.ResetState) @@ -109,9 +111,7 @@ class TapWalletManager { val config = store.state.globalState.configManager?.config ?: return@withContext store.dispatch(WalletAction.LoadWallet( - data.walletManager.wallet, data.verifyResponse?.artworkInfo?.id, - tapWorkarounds?.isStart2Coin == false && config.isTopUpEnabled - )) + data.walletManager.wallet, data.verifyResponse?.artworkInfo?.id, config.isTopUpEnabled)) store.dispatch(WalletAction.LoadArtwork(data.card, artworkId)) store.dispatch(WalletAction.LoadFiatRate) store.dispatch(WalletAction.LoadPayId) diff --git a/app/src/main/java/com/tangem/tap/domain/config/ConfigManager.kt b/app/src/main/java/com/tangem/tap/domain/config/ConfigManager.kt index 668339cd20..339aeb3124 100644 --- a/app/src/main/java/com/tangem/tap/domain/config/ConfigManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/config/ConfigManager.kt @@ -34,7 +34,7 @@ class ConfigManager( } } - fun turnOf(name: String) { + fun turnOff(name: String) { when (name) { isWalletPayIdEnabled -> config = config.copy(isWalletPayIdEnabled = false) isTopUpEnabled -> config = config.copy(isTopUpEnabled = false) From 9f49590236f1a4a762803cf532511e3ff8d847d8 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 25 Nov 2020 23:30:16 +0300 Subject: [PATCH 21/21] Updated on 2026-08-14 --- .../com/tangem/tap/domain/TapWalletManager.kt | 16 +++++++++------- .../java/com/tangem/tap/domain/TapWorkarounds.kt | 5 ----- .../tap/features/send/redux/SendScreenAction.kt | 1 + .../redux/middlewares/AddressPayIdMiddleware.kt | 12 ++++++++---- .../send/redux/reducers/AddressPayIdReducer.kt | 1 + .../send/redux/states/AddressPayIdState.kt | 1 + .../ui/stateSubscribers/SendStateSubscriber.kt | 3 +-- 7 files changed, 21 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt index 82d4d105bc..27d0665a61 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt @@ -14,6 +14,7 @@ import com.tangem.tap.domain.config.ConfigManager import com.tangem.tap.domain.extensions.amountToCreateAccount import com.tangem.tap.domain.extensions.isNoAccountError import com.tangem.tap.domain.tasks.ScanNoteResponse +import com.tangem.tap.features.send.redux.AddressPayIdActionUi import com.tangem.tap.features.wallet.redux.WalletAction import com.tangem.tap.network.NetworkConnectivity import com.tangem.tap.network.coinmarketcap.CoinMarketCapService @@ -26,7 +27,6 @@ import java.math.BigDecimal class TapWalletManager { private val payIdManager = PayIdManager() private val coinMarketCapService = CoinMarketCapService() - private var tapWorkarounds: TapWorkarounds? = null suspend fun loadWalletData() { val walletManager = store.state.globalState.scanNoteResponse?.walletManager @@ -84,17 +84,19 @@ class TapWalletManager { if (addAnalyticsEvent) { FirebaseAnalyticsHandler.triggerEvent(AnalyticsEvent.CARD_IS_SCANNED, data.card) } - tapWorkarounds = TapWorkarounds(data.card) - if (tapWorkarounds!!.isStart2Coin) { - store.state.globalState.configManager?.turnOff(ConfigManager.isWalletPayIdEnabled) - store.state.globalState.configManager?.turnOff(ConfigManager.isTopUpEnabled) + TapWorkarounds.updateCard(data.card) + val configManager = store.state.globalState.configManager + if (TapWorkarounds.isStart2Coin) { + configManager?.turnOff(ConfigManager.isWalletPayIdEnabled) + configManager?.turnOff(ConfigManager.isTopUpEnabled) } else { - store.state.globalState.configManager?.resetToDefault(ConfigManager.isWalletPayIdEnabled) - store.state.globalState.configManager?.resetToDefault(ConfigManager.isTopUpEnabled) + configManager?.resetToDefault(ConfigManager.isWalletPayIdEnabled) + configManager?.resetToDefault(ConfigManager.isTopUpEnabled) } withContext(Dispatchers.Main) { store.dispatch(WalletAction.ResetState) store.dispatch(GlobalAction.SaveScanNoteResponse(data)) + store.dispatch(AddressPayIdActionUi.ChangePayIdState(configManager?.config?.isWalletPayIdEnabled ?: false)) loadData(data) } } diff --git a/app/src/main/java/com/tangem/tap/domain/TapWorkarounds.kt b/app/src/main/java/com/tangem/tap/domain/TapWorkarounds.kt index de1640fd9c..bb5e44f015 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapWorkarounds.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapWorkarounds.kt @@ -12,10 +12,5 @@ object TapWorkarounds { isStart2Coin = card.cardData?.issuerName?.toLowerCase(Locale.US) == START_2_COIN_ISSUER } - fun isPayIdEnabled(): Boolean { - if (isStart2Coin) return false - return true - } - const val START_2_COIN_ISSUER = "start2coin" } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt b/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt index 911a51af79..e54f0f07dc 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt @@ -33,6 +33,7 @@ sealed class AddressPayIdActionUi : SendScreenActionUi { object CheckAddressPayId : AddressPayIdActionUi() data class SetTruncateHandler(val handler: (String) -> String) : AddressPayIdActionUi() data class TruncateOrRestore(val truncate: Boolean) : AddressPayIdActionUi() + data class ChangePayIdState(val walletPayIdEnabled: Boolean): AddressPayIdActionUi() } sealed class AddressPayIdVerifyAction : SendScreenAction { diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AddressPayIdMiddleware.kt b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AddressPayIdMiddleware.kt index 680654633b..74fdac0d5d 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AddressPayIdMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AddressPayIdMiddleware.kt @@ -4,7 +4,6 @@ import com.tangem.blockchain.common.Wallet import com.tangem.commands.common.network.Result import com.tangem.tap.common.redux.AppState import com.tangem.tap.domain.PayIdManager -import com.tangem.tap.domain.TapWorkarounds import com.tangem.tap.domain.isPayIdSupported import com.tangem.tap.features.send.redux.AddressPayIdActionUi import com.tangem.tap.features.send.redux.AddressPayIdVerifyAction @@ -15,6 +14,7 @@ import com.tangem.tap.features.send.redux.AddressPayIdVerifyAction.PayIdVerifica import com.tangem.tap.features.send.redux.AddressPayIdVerifyAction.PayIdVerification.SetPayIdWalletAddress import com.tangem.tap.features.send.redux.FeeAction import com.tangem.tap.scope +import com.tangem.tap.store import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -49,7 +49,7 @@ internal class AddressPayIdMiddleware { private fun setAddressAndCheck(data: String, isUserInput: Boolean, dispatch: (Action) -> Unit) { val potentialPayId = data.toLowerCase() - if (PayIdManager.isPayId(potentialPayId) && TapWorkarounds.isPayIdEnabled()) { + if (PayIdManager.isPayId(potentialPayId) && isPayIdEnabled()) { dispatch(SetPayIdWalletAddress(potentialPayId, "", isUserInput)) } else { dispatch(SetWalletAddress(data, isUserInput)) @@ -63,7 +63,7 @@ internal class AddressPayIdMiddleware { val addressPayId = sendState.addressPayIdState.normalFieldValue ?: return val isUserInput = sendState.addressPayIdState.viewFieldValue.isFromUserInput - if (PayIdManager.isPayId(addressPayId) && TapWorkarounds.isPayIdEnabled()) { + if (PayIdManager.isPayId(addressPayId) && isPayIdEnabled()) { verifyPayId(addressPayId, wallet, isUserInput, dispatch) } else { verifyAddress(addressPayId, wallet, isUserInput, dispatch) @@ -152,10 +152,14 @@ internal class AddressPayIdMiddleware { } } - if (PayIdManager.isPayId(addressPayId) && TapWorkarounds.isPayIdEnabled()) { + if (PayIdManager.isPayId(addressPayId) && isPayIdEnabled()) { verifyPayId(addressPayId, wallet, false, internalDispatcher) } else { verifyAddress(addressPayId, wallet, false, internalDispatcher) } } + + private fun isPayIdEnabled(): Boolean { + return store.state.globalState.configManager?.config?.isWalletPayIdEnabled ?: false + } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/AddressPayIdReducer.kt b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/AddressPayIdReducer.kt index e7c726241f..d7a1c97f10 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/AddressPayIdReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/AddressPayIdReducer.kt @@ -30,6 +30,7 @@ class AddressPayIdReducer : SendInternalReducer { is AddressPayIdActionUi.PasteAddressPayId -> return sendState is AddressPayIdActionUi.CheckClipboard -> return sendState is AddressPayIdActionUi.CheckAddressPayId -> return sendState + is AddressPayIdActionUi.ChangePayIdState -> state.copy(walletPayIdEnabled = action.walletPayIdEnabled) } return updateLastState(sendState.copy(addressPayIdState = result), result) } diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/states/AddressPayIdState.kt b/app/src/main/java/com/tangem/tap/features/send/redux/states/AddressPayIdState.kt index dfcc6ca4c5..b7a1622789 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/states/AddressPayIdState.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/states/AddressPayIdState.kt @@ -9,6 +9,7 @@ data class AddressPayIdState( val recipientWalletAddress: String? = null, val error: AddressPayIdVerifyAction.Error? = null, val truncateHandler: ((String) -> String)? = null, + val walletPayIdEnabled: Boolean = false, val pasteIsEnabled: Boolean = false ) : SendScreenState { diff --git a/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt b/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt index bdd2e9f3c4..c6065b1752 100644 --- a/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt +++ b/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt @@ -10,7 +10,6 @@ import com.tangem.tap.common.redux.getMessageString import com.tangem.tap.common.text.DecimalDigitsInputFilter import com.tangem.tap.common.toggleWidget.ProgressState import com.tangem.tap.domain.MultiMessageError -import com.tangem.tap.domain.TapWorkarounds import com.tangem.tap.domain.assembleErrors import com.tangem.tap.features.send.BaseStoreFragment import com.tangem.tap.features.send.redux.AddressPayIdVerifyAction.Error @@ -104,7 +103,7 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber val til = fg.tilAddressOrPayId val parsedError = parseError(til.context, state.error) - val hintResId = if (TapWorkarounds.isPayIdEnabled()) { + val hintResId = if (state.walletPayIdEnabled) { R.string.send_destination_hint_address_payid }else { R.string.send_destination_hint_address