From 6997dd476aca4973c0fedb21177e49765408e94f Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 25 Sep 2025 12:17:32 +0300 Subject: [PATCH 01/13] Updated on 2026-08-14 --- .../features/onramp/main/entity/OnrampIntents.kt | 2 +- .../onramp/main/entity/factory/OnrampStateFactory.kt | 2 +- .../factory/amount/OnrampAmountFieldChangeConverter.kt | 10 ++++++++-- .../entity/factory/amount/OnrampAmountStateFactory.kt | 3 ++- .../onramp/main/model/OnrampMainComponentModel.kt | 6 +++--- 5 files changed, 15 insertions(+), 8 deletions(-) diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/entity/OnrampIntents.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/entity/OnrampIntents.kt index 5654a17174..0115a77152 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/entity/OnrampIntents.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/entity/OnrampIntents.kt @@ -3,7 +3,7 @@ package com.tangem.features.onramp.main.entity import com.tangem.domain.onramp.model.OnrampProviderWithQuote interface OnrampIntents { - fun onAmountValueChanged(value: String) + fun onAmountValueChanged(value: String, isValuePasted: Boolean) fun openSettings() fun openCurrenciesList() fun onBuyClick(quote: OnrampProviderWithQuote.Data) diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/entity/factory/OnrampStateFactory.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/entity/factory/OnrampStateFactory.kt index bfd3db959d..09da044da3 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/entity/factory/OnrampStateFactory.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/entity/factory/OnrampStateFactory.kt @@ -122,7 +122,7 @@ internal class OnrampStateFactory( amountFieldModel = AmountFieldModel( value = "", fiatValue = "", - onValueChange = onrampIntents::onAmountValueChanged, + onValueChange = { onrampIntents.onAmountValueChanged(value = it, isValuePasted = false) }, keyboardOptions = KeyboardOptions( imeAction = ImeAction.None, keyboardType = KeyboardType.Number, diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/entity/factory/amount/OnrampAmountFieldChangeConverter.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/entity/factory/amount/OnrampAmountFieldChangeConverter.kt index 576bbe719e..02c3f9fa33 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/entity/factory/amount/OnrampAmountFieldChangeConverter.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/entity/factory/amount/OnrampAmountFieldChangeConverter.kt @@ -15,9 +15,12 @@ import java.math.BigDecimal internal class OnrampAmountFieldChangeConverter( private val currentStateProvider: Provider, -) : Converter { +) : Converter { + + override fun convert(input: Input): OnrampMainComponentUM { + val value = input.value + val isValuePasted = input.isValuePasted - override fun convert(value: String): OnrampMainComponentUM { val state = currentStateProvider() if (state !is OnrampMainComponentUM.Content) return state @@ -34,6 +37,7 @@ internal class OnrampAmountFieldChangeConverter( imeAction = if (isDoneActionEnabled) ImeAction.Done else ImeAction.None, keyboardType = KeyboardType.Number, ), + isValuePasted = isValuePasted, ) return state.copy( @@ -66,4 +70,6 @@ internal class OnrampAmountFieldChangeConverter( providerBlockState = OnrampProviderBlockUM.Empty, ) } + + data class Input(val value: String, val isValuePasted: Boolean) } \ No newline at end of file diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/entity/factory/amount/OnrampAmountStateFactory.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/entity/factory/amount/OnrampAmountStateFactory.kt index 2ad9356378..4d466907aa 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/entity/factory/amount/OnrampAmountStateFactory.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/entity/factory/amount/OnrampAmountStateFactory.kt @@ -33,7 +33,8 @@ internal class OnrampAmountStateFactory( currentStateProvider = currentStateProvider, ) - fun getOnAmountValueChange(value: String) = onrampAmountFieldChangeConverter.convert(value) + fun getOnAmountValueChange(value: String, isValuePasted: Boolean) = + onrampAmountFieldChangeConverter.convert(OnrampAmountFieldChangeConverter.Input(value, isValuePasted)) fun getUpdatedCurrencyState(currency: OnrampCurrency): OnrampMainComponentUM { val currentState = currentStateProvider() diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/model/OnrampMainComponentModel.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/model/OnrampMainComponentModel.kt index 832304f55a..1a415ee735 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/model/OnrampMainComponentModel.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/model/OnrampMainComponentModel.kt @@ -171,7 +171,7 @@ internal class OnrampMainComponentModel @Inject constructor( updatePairsAndQuotes() if (wasInitialLoading && params.launchSepa) { - onAmountValueChanged(PREDEFINED_SEPA_AMOUNT) + onAmountValueChanged(value = PREDEFINED_SEPA_AMOUNT, isValuePasted = true) } }, ) @@ -243,8 +243,8 @@ internal class OnrampMainComponentModel @Inject constructor( .launchIn(modelScope) } - override fun onAmountValueChanged(value: String) { - _state.update { amountStateFactory.getOnAmountValueChange(value) } + override fun onAmountValueChanged(value: String, isValuePasted: Boolean) { + _state.update { amountStateFactory.getOnAmountValueChange(value, isValuePasted) } modelScope.launch { amountInputManager.update(value) } } From 148d7183596423210bfbe2453cf825095185dd32 Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 25 Sep 2025 12:22:05 +0300 Subject: [PATCH 02/13] Updated on 2026-08-14 --- .../java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt index 05128a4991..d01b686595 100644 --- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt +++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt @@ -410,7 +410,7 @@ internal class SwapInteractorImpl @AssistedInject constructor( rateType = RateType.FLOAT, ) - return if (isBalanceWithoutFeeEnough) { + return if (isBalanceWithoutFeeEnough && maybeQuotes.isRight()) { provider to loadDexSwapData( provider = provider, networkId = networkId, From 0d4fe013427f40dd8cdb2fcf0cd4a83c5de79156 Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 25 Sep 2025 11:41:09 +0000 Subject: [PATCH 03/13] Updated on 2026-08-14 --- gradle/tangem_dependencies.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gradle/tangem_dependencies.toml b/gradle/tangem_dependencies.toml index a197db179d..4e84217654 100644 --- a/gradle/tangem_dependencies.toml +++ b/gradle/tangem_dependencies.toml @@ -5,13 +5,13 @@ # https://github.com/tangem/tangem-sdk-android/ # https://github.com/tangem/vico -tangemBlockchainSdk = "releases-5.28-1241" +tangemBlockchainSdk = "releases-5.29-1238" #tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds -tangemCardSdk = "releases-5.28-563" +tangemCardSdk = "releases-5.29-565" #tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^ tangemVico = "2.0.0-alpha.25-tangem12" #tangemVico = "0.0.1" # Keep it! - used for local builds ^ -tangemHotSdk = "develop-461" +tangemHotSdk = "develop-528" #tangemHotSdk = "0.0.1" # Keep it! - used for local builds ^ From 42a9b57ee9a6802d09d28a7d90fa24af7f015313 Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 25 Sep 2025 16:41:59 +0300 Subject: [PATCH 04/13] Updated on 2026-08-14 --- .../confirmresidency/ConfirmResidencyComponent.kt | 1 + .../confirmresidency/model/ConfirmResidencyModel.kt | 7 +++++++ .../onramp/main/DefaultOnrampMainComponent.kt | 1 + .../onramp/main/model/OnrampMainComponentModel.kt | 9 +-------- .../onramp/mainv2/DefaultOnrampV2MainComponent.kt | 1 + .../tangem/features/onramp/utils/model/EurCurrency.kt | 11 +++++++++++ 6 files changed, 22 insertions(+), 8 deletions(-) create mode 100644 features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/utils/model/EurCurrency.kt diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/confirmresidency/ConfirmResidencyComponent.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/confirmresidency/ConfirmResidencyComponent.kt index df3299765b..6942e44992 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/confirmresidency/ConfirmResidencyComponent.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/confirmresidency/ConfirmResidencyComponent.kt @@ -12,6 +12,7 @@ internal interface ConfirmResidencyComponent : ComposableBottomSheetComponent { val userWalletId: UserWalletId, val cryptoCurrency: CryptoCurrency, val country: OnrampCountry, + val launchSepa: Boolean, val onDismiss: () -> Unit, ) diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/confirmresidency/model/ConfirmResidencyModel.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/confirmresidency/model/ConfirmResidencyModel.kt index 3466152b67..724ec2e7a4 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/confirmresidency/model/ConfirmResidencyModel.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/confirmresidency/model/ConfirmResidencyModel.kt @@ -9,12 +9,14 @@ import com.tangem.core.decompose.model.ParamsContainer import com.tangem.core.decompose.navigation.Router import com.tangem.core.ui.extensions.resourceReference import com.tangem.domain.onramp.OnrampSaveDefaultCountryUseCase +import com.tangem.domain.onramp.OnrampSaveDefaultCurrencyUseCase import com.tangem.domain.onramp.analytics.OnrampAnalyticsEvent import com.tangem.domain.onramp.model.OnrampCountry import com.tangem.features.onramp.confirmresidency.ConfirmResidencyComponent import com.tangem.features.onramp.confirmresidency.entity.ConfirmResidencyBottomSheetConfig import com.tangem.features.onramp.confirmresidency.entity.ConfirmResidencyUM import com.tangem.features.onramp.impl.R +import com.tangem.features.onramp.utils.model.EUR_CURRENCY import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.launch @@ -26,6 +28,7 @@ internal class ConfirmResidencyModel @Inject constructor( private val analyticsEventHandler: AnalyticsEventHandler, private val router: Router, private val saveDefaultCountryUseCase: OnrampSaveDefaultCountryUseCase, + private val onrampSaveDefaultCurrencyUseCase: OnrampSaveDefaultCurrencyUseCase, paramsContainer: ParamsContainer, ) : Model() { @@ -54,6 +57,10 @@ internal class ConfirmResidencyModel @Inject constructor( analyticsEventHandler.send(OnrampAnalyticsEvent.OnResidenceConfirm(country.name)) modelScope.launch { saveDefaultCountryUseCase.invoke(country) + if (params.launchSepa) { + onrampSaveDefaultCurrencyUseCase.invoke(EUR_CURRENCY) + } + params.onDismiss() } }, diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/DefaultOnrampMainComponent.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/DefaultOnrampMainComponent.kt index 0f959bb2c2..d03c60d6d0 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/DefaultOnrampMainComponent.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/DefaultOnrampMainComponent.kt @@ -57,6 +57,7 @@ internal class DefaultOnrampMainComponent @AssistedInject constructor( userWalletId = params.userWalletId, cryptoCurrency = params.cryptoCurrency, country = config.country, + launchSepa = params.launchSepa, onDismiss = { model.bottomSheetNavigation.dismiss() model.handleOnrampAvailable() diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/model/OnrampMainComponentModel.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/model/OnrampMainComponentModel.kt index 1a415ee735..d145a6dc4c 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/model/OnrampMainComponentModel.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/model/OnrampMainComponentModel.kt @@ -32,6 +32,7 @@ import com.tangem.features.onramp.main.entity.factory.OnrampStateFactory import com.tangem.features.onramp.main.entity.factory.OnrampStateFactory.Companion.PREDEFINED_SEPA_AMOUNT import com.tangem.features.onramp.main.entity.factory.amount.OnrampAmountStateFactory import com.tangem.features.onramp.providers.entity.SelectProviderResult +import com.tangem.features.onramp.utils.model.EUR_CURRENCY import com.tangem.features.onramp.utils.sendOnrampErrorEvent import com.tangem.utils.Provider import com.tangem.utils.coroutines.CoroutineDispatcherProvider @@ -456,13 +457,5 @@ internal class OnrampMainComponentModel @Inject constructor( const val UPDATE_DELAY = 10_000L const val SEPA_METHOD_ID = "sepa" - - val EUR_CURRENCY = OnrampCurrency( - code = "EUR", - name = "Euro", - unit = "€", - precision = 2, - image = "https://s3.eu-central-1.amazonaws.com/tangem.api/express/Currencies/EUR.png", - ) } } \ No newline at end of file diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/mainv2/DefaultOnrampV2MainComponent.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/mainv2/DefaultOnrampV2MainComponent.kt index af62d7ecbe..008cf19772 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/mainv2/DefaultOnrampV2MainComponent.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/mainv2/DefaultOnrampV2MainComponent.kt @@ -58,6 +58,7 @@ internal class DefaultOnrampV2MainComponent @AssistedInject constructor( userWalletId = params.userWalletId, cryptoCurrency = params.cryptoCurrency, country = config.country, + launchSepa = false, onDismiss = { model.bottomSheetNavigation.dismiss() }, ), ) diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/utils/model/EurCurrency.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/utils/model/EurCurrency.kt new file mode 100644 index 0000000000..6f75fc6908 --- /dev/null +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/utils/model/EurCurrency.kt @@ -0,0 +1,11 @@ +package com.tangem.features.onramp.utils.model + +import com.tangem.domain.onramp.model.OnrampCurrency + +internal val EUR_CURRENCY = OnrampCurrency( + code = "EUR", + name = "Euro", + unit = "€", + precision = 2, + image = "https://s3.eu-central-1.amazonaws.com/tangem.api/express/Currencies/EUR.png", +) \ No newline at end of file From 2a85a3ce3250c46974a4e087b79aadd9b2976b0d Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 25 Sep 2025 16:59:43 +0300 Subject: [PATCH 05/13] Updated on 2026-08-14 --- .../onramp/main/entity/OnrampLastUpdate.kt | 6 +++-- .../main/model/OnrampMainComponentModel.kt | 27 ++++++++++++------- .../model/OnrampV2MainComponentModel.kt | 9 ++++--- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/entity/OnrampLastUpdate.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/entity/OnrampLastUpdate.kt index bc6113303c..9bcc516c6b 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/entity/OnrampLastUpdate.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/entity/OnrampLastUpdate.kt @@ -1,8 +1,10 @@ package com.tangem.features.onramp.main.entity import com.tangem.domain.onramp.model.OnrampAmount +import com.tangem.domain.onramp.model.OnrampPaymentMethod data class OnrampLastUpdate( - val lastAmount: OnrampAmount, - val lastCountryString: String, + val fromAmount: OnrampAmount, + val countryCode: String, + val paymentMethod: OnrampPaymentMethod, ) \ No newline at end of file diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/model/OnrampMainComponentModel.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/model/OnrampMainComponentModel.kt index d145a6dc4c..6b3a4d73a6 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/model/OnrampMainComponentModel.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/model/OnrampMainComponentModel.kt @@ -69,7 +69,7 @@ internal class OnrampMainComponentModel @Inject constructor( private val params: OnrampMainComponent.Params = paramsContainer.require() - private var isSepaLaunched = false + private var shouldForceChooseSepa = params.launchSepa private var currencyToRestore: OnrampCurrency? = null val userWallet = getWalletsUseCase.invokeSync().first { it.walletId == params.userWalletId } @@ -133,6 +133,10 @@ internal class OnrampMainComponentModel @Inject constructor( fun onProviderSelected(result: SelectProviderResult, isBestRate: Boolean) { _state.update { amountStateFactory.getAmountSecondaryUpdatedState(result, isBestRate) } + + if (result.paymentMethod.id != SEPA_METHOD_ID) { + shouldForceChooseSepa = false + } } private fun checkResidenceCountry() { @@ -342,9 +346,7 @@ internal class OnrampMainComponentModel @Inject constructor( private fun selectOrUpdateQuote(quotes: List): OnrampQuote? { val quoteToCheck = quotes.firstOrNull { it !is OnrampQuote.Error } - val sepaQuote = if (params.launchSepa && !isSepaLaunched) { - isSepaLaunched = true - + val bestSepaQuote = if (params.launchSepa && shouldForceChooseSepa) { quotes.filterIsInstance() .filter { it.paymentMethod.id == SEPA_METHOD_ID } .maxByOrNull { it.toAmount.value } @@ -353,7 +355,7 @@ internal class OnrampMainComponentModel @Inject constructor( } // Check if amount, country or currency has changed - val newQuote = sepaQuote ?: if (checkLastInputState(quoteToCheck)) { + val newQuote = bestSepaQuote ?: if (isAmountOrCountryChanged(quoteToCheck)) { quoteToCheck } else { val state = state.value as? OnrampMainComponentUM.Content @@ -372,7 +374,9 @@ internal class OnrampMainComponentModel @Inject constructor( lastSelectedQuote } } - newQuote?.let { updateProvider(newQuote, quotes) } + if (newQuote != null) { + updateProvider(newQuote, quotes) + } return newQuote } @@ -381,8 +385,13 @@ internal class OnrampMainComponentModel @Inject constructor( lastUpdateState.value = OnrampLastUpdate( quote.fromAmount, quote.countryCode, + quote.paymentMethod, ) + if (quote.paymentMethod.id != SEPA_METHOD_ID) { + shouldForceChooseSepa = false + } + _state.update { amountStateFactory.getUpdatedProviderState(selectedQuote = quote, quotes = quotes) } @@ -448,9 +457,9 @@ internal class OnrampMainComponentModel @Inject constructor( } } - private fun checkLastInputState(quote: OnrampQuote?): Boolean { - return lastUpdateState.value?.lastAmount != quote?.fromAmount || - lastUpdateState.value?.lastCountryString != quote?.countryCode + private fun isAmountOrCountryChanged(quote: OnrampQuote?): Boolean { + return lastUpdateState.value?.fromAmount != quote?.fromAmount || + lastUpdateState.value?.countryCode != quote?.countryCode } private companion object { diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/mainv2/model/OnrampV2MainComponentModel.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/mainv2/model/OnrampV2MainComponentModel.kt index 93f199fc85..834518bbb3 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/mainv2/model/OnrampV2MainComponentModel.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/mainv2/model/OnrampV2MainComponentModel.kt @@ -348,8 +348,9 @@ internal class OnrampV2MainComponentModel @Inject constructor( private fun updateProvider(quote: OnrampQuote) { lastUpdateState.value = OnrampLastUpdate( - quote.fromAmount, - quote.countryCode, + fromAmount = quote.fromAmount, + countryCode = quote.countryCode, + paymentMethod = quote.paymentMethod, ) _state.update { @@ -378,8 +379,8 @@ internal class OnrampV2MainComponentModel @Inject constructor( } private fun checkLastInputState(quote: OnrampQuote?): Boolean { - return lastUpdateState.value?.lastAmount != quote?.fromAmount || - lastUpdateState.value?.lastCountryString != quote?.countryCode + return lastUpdateState.value?.fromAmount != quote?.fromAmount || + lastUpdateState.value?.countryCode != quote?.countryCode } private fun sendScreenOpenAnalytics() { From 9478a17d367b846450a77dbff12df92d8db88022 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 26 Sep 2025 17:21:25 +0300 Subject: [PATCH 06/13] Updated on 2026-08-14 --- .../tangem/tap/ForegroundActivityObserver.kt | 20 +++++++++++++------ .../main/java/com/tangem/tap/MainActivity.kt | 4 ++++ .../java/com/tangem/tap/TangemApplication.kt | 16 +++++++++------ 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/ForegroundActivityObserver.kt b/app/src/main/java/com/tangem/tap/ForegroundActivityObserver.kt index cb7805793c..98ce5cd24b 100644 --- a/app/src/main/java/com/tangem/tap/ForegroundActivityObserver.kt +++ b/app/src/main/java/com/tangem/tap/ForegroundActivityObserver.kt @@ -4,30 +4,38 @@ import android.app.Activity import android.app.Application.ActivityLifecycleCallbacks import android.os.Bundle import androidx.appcompat.app.AppCompatActivity -import java.util.WeakHashMap +import timber.log.Timber import kotlin.reflect.KClass -class ForegroundActivityObserver { +object ForegroundActivityObserver { - private val activities = WeakHashMap, AppCompatActivity>() + private val activities = HashMap, AppCompatActivity>() val foregroundActivity: AppCompatActivity? get() = activities.entries - .firstOrNull { it.value?.isDestroyed == false } + .firstOrNull { + Timber.i("foregroundActivity: ${it.key} | ${it.value.isDestroyed}") + it.value.isDestroyed == false + } ?.value internal val callbacks: ActivityLifecycleCallbacks get() = Callbacks() - internal inner class Callbacks : ActivityLifecycleCallbacks { + internal class Callbacks : ActivityLifecycleCallbacks { override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) { } override fun onActivityResumed(activity: Activity) { - activities[activity::class] = activity as? AppCompatActivity + Timber.i("onActivityResumed ${activity::class}") + (activity as? AppCompatActivity)?.let { + Timber.i("onActivityResumed store activity") + activities[activity::class] = it + } } override fun onActivityDestroyed(activity: Activity) { + Timber.i("onActivityDestroyed") activities.remove(activity::class) } diff --git a/app/src/main/java/com/tangem/tap/MainActivity.kt b/app/src/main/java/com/tangem/tap/MainActivity.kt index c047e66353..24653ac2e5 100644 --- a/app/src/main/java/com/tangem/tap/MainActivity.kt +++ b/app/src/main/java/com/tangem/tap/MainActivity.kt @@ -191,6 +191,7 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder { private val onActivityResultCallbacks = mutableListOf() override fun onCreate(savedInstanceState: Bundle?) { + Timber.i("onCreate") // We need to call it before onCreate to prevent unnecessary activity recreation installAppTheme() @@ -328,15 +329,18 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder { override fun onStart() { super.onStart() + Timber.i("onStart") dialogManager.onStart(this) } override fun onStop() { dialogManager.onStop() super.onStop() + Timber.i("onStop") } override fun onDestroy() { + Timber.i("onDestroy") // workaround: kill process when activity destroy to avoid state when lock() wallets // and navigation to unlock screen was skipped because system kills activity but not process if (BuildConfig.BUILD_TYPE != MOCKED_BUILD_TYPE) { diff --git a/app/src/main/java/com/tangem/tap/TangemApplication.kt b/app/src/main/java/com/tangem/tap/TangemApplication.kt index 9a3f617366..8adc257a55 100644 --- a/app/src/main/java/com/tangem/tap/TangemApplication.kt +++ b/app/src/main/java/com/tangem/tap/TangemApplication.kt @@ -85,7 +85,7 @@ import timber.log.Timber lateinit var store: Store -lateinit var foregroundActivityObserver: ForegroundActivityObserver +val foregroundActivityObserver = ForegroundActivityObserver internal lateinit var derivationsFinder: DerivationsFinder abstract class TangemApplication : Application(), ImageLoaderFactory, Configuration.Provider { @@ -246,6 +246,7 @@ abstract class TangemApplication : Application(), ImageLoaderFactory, Configurat override fun onCreate() { enableStrictModeInDebug() + preInit() super.onCreate() init() } @@ -286,22 +287,25 @@ abstract class TangemApplication : Application(), ImageLoaderFactory, Configurat // } } + /** + * Initialize components that need to be initialized before [super.onCreate] is called + */ + private fun preInit() { + tangemAppLoggerInitializer.initialize() + registerActivityLifecycleCallbacks(foregroundActivityObserver.callbacks) + } + fun init() { apiConfigsManager.initialize() store = createReduxStore() - tangemAppLoggerInitializer.initialize() - Timber.i("APP STARTED") if (BuildConfig.TESTER_MENU_ENABLED) { Timber.i(featureTogglesManager.toString()) Timber.i(excludedBlockchainsManager.toString()) } - foregroundActivityObserver = ForegroundActivityObserver() - registerActivityLifecycleCallbacks(foregroundActivityObserver.callbacks) - runBlocking { initWithConfigDependency(environmentConfig = environmentConfigStorage.initialize()) } From 535e9caa040e65f8d7c135c992c344188a87b7f4 Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 29 Sep 2025 12:52:54 +0300 Subject: [PATCH 07/13] Updated on 2026-08-14 --- gradle/tangem_dependencies.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/tangem_dependencies.toml b/gradle/tangem_dependencies.toml index 4e84217654..d1e39a0355 100644 --- a/gradle/tangem_dependencies.toml +++ b/gradle/tangem_dependencies.toml @@ -5,7 +5,7 @@ # https://github.com/tangem/tangem-sdk-android/ # https://github.com/tangem/vico -tangemBlockchainSdk = "releases-5.29-1238" +tangemBlockchainSdk = "releases-5.29-1249" #tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds tangemCardSdk = "releases-5.29-565" #tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^ From de2ac281ab2452153fb4fe13ea4bc5862e5cf8de Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 26 Sep 2025 10:55:42 +0500 Subject: [PATCH 08/13] Updated on 2026-08-14 --- .../send/v2/send/confirm/model/SendConfirmModel.kt | 2 +- .../v2/send/success/model/SendConfirmSuccessModel.kt | 10 +++++----- .../v2/sendnft/confirm/model/NFTSendConfirmModel.kt | 2 +- .../success/model/SendWithSwapSuccessModel.kt | 10 +++++----- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/model/SendConfirmModel.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/model/SendConfirmModel.kt index 5d669c9b93..2a22a8c5b6 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/model/SendConfirmModel.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/model/SendConfirmModel.kt @@ -510,7 +510,7 @@ internal class SendConfirmModel @Inject constructor( val txUrl = getExplorerTransactionUrlUseCase( txHash = txData.hash.orEmpty(), networkId = cryptoCurrency.network.id, - ).getOrElse { "" } + ).getOrNull().orEmpty() _uiState.update(SendConfirmSentStateTransformer(txData, txUrl)) } diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/success/model/SendConfirmSuccessModel.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/success/model/SendConfirmSuccessModel.kt index 80bdafb04f..87680abfc2 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/success/model/SendConfirmSuccessModel.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/success/model/SendConfirmSuccessModel.kt @@ -76,15 +76,15 @@ internal class SendConfirmSuccessModel @Inject constructor( }, ), prevButton = null, - secondaryPairButtonsUM = NavigationButton( + secondaryPairButtonsUM = (NavigationButton( textReference = resourceReference(R.string.common_explore), iconRes = R.drawable.ic_web_24, onClick = ::onExploreClick, ) to NavigationButton( - textReference = resourceReference(R.string.common_share), - iconRes = R.drawable.ic_share_24, - onClick = ::onShareClick, - ), + textReference = resourceReference(R.string.common_share), + iconRes = R.drawable.ic_share_24, + onClick = ::onShareClick, + )).takeIf { params.txUrl.isNotEmpty() }, ), ), ) diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/sendnft/confirm/model/NFTSendConfirmModel.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/sendnft/confirm/model/NFTSendConfirmModel.kt index bd7ff87906..7204187015 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/sendnft/confirm/model/NFTSendConfirmModel.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/sendnft/confirm/model/NFTSendConfirmModel.kt @@ -498,7 +498,7 @@ internal class NFTSendConfirmModel @Inject constructor( iconRes = R.drawable.ic_share_24, onClick = ::onShareClick, ) - ).takeIf { confirmUM is ConfirmUM.Success }, + ).takeUnless { (confirmUM as? ConfirmUM.Success)?.txUrl.isNullOrBlank() }, ), ), ) diff --git a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/success/model/SendWithSwapSuccessModel.kt b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/success/model/SendWithSwapSuccessModel.kt index 63ad5d40da..ba7331c157 100644 --- a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/success/model/SendWithSwapSuccessModel.kt +++ b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/success/model/SendWithSwapSuccessModel.kt @@ -52,15 +52,15 @@ internal class SendWithSwapSuccessModel @Inject constructor( onClick = appRouter::pop, ), prevButton = null, - secondaryPairButtonsUM = NavigationButton( + secondaryPairButtonsUM = (NavigationButton( textReference = resourceReference(R.string.common_explore), iconRes = R.drawable.ic_web_24, onClick = ::onExploreClick, ) to NavigationButton( - textReference = resourceReference(R.string.common_share), - iconRes = R.drawable.ic_share_24, - onClick = ::onShareClick, - ), + textReference = resourceReference(R.string.common_share), + iconRes = R.drawable.ic_share_24, + onClick = ::onShareClick, + )).takeUnless { confirmUM?.txUrl.isNullOrBlank() }, ), ) } From 2898ff1fa266dc0fc204b5798edbc2ecd6bbc1bf Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 29 Sep 2025 15:43:07 +0300 Subject: [PATCH 09/13] Updated on 2026-08-14 --- core/res/src/main/res/values-ja/strings.xml | 12 ++++++++-- core/res/src/main/res/values-ru/strings.xml | 4 ++++ core/res/src/main/res/values/strings.xml | 19 +++++++++++---- .../solana/WcSolanaSignTransactionUseCase.kt | 3 +++ .../domain/walletconnect/WcAnalyticEvents.kt | 23 +++++++++++++++++++ .../model/WcSendTransactionModel.kt | 2 ++ 6 files changed, 56 insertions(+), 7 deletions(-) diff --git a/core/res/src/main/res/values-ja/strings.xml b/core/res/src/main/res/values-ja/strings.xml index aebdb99134..bd9bd6be0d 100644 --- a/core/res/src/main/res/values-ja/strings.xml +++ b/core/res/src/main/res/values-ja/strings.xml @@ -19,7 +19,10 @@ 回復する 「 %1$s 」を回復しようとしています。 アカウントを回復する + すでにアクティブアカウント数の上限(20件)を超えています。復元するには1件アーカイブしてください。 + アカウントを復元できません アーカイブ済み + アカウントを作成できませんでした。しばらくしてからもう一度お試しください。 アカウントを作成しました アカウントをアーカイブする アーカイブ @@ -258,6 +261,7 @@ 残り%1$s レガシービットコイン ロックされています + ロックされたウォレット メインネットワーク ネットワーク手数料 @@ -307,6 +311,7 @@ 署名 署名して送信 スキップ + 問題が発生しました ステーキング ステーキング 始める @@ -1143,7 +1148,7 @@ 獲得した報酬をステーキングに再投資し、潜在的な収益を増やします。 再ステーキングを使うと、ステーキングを解除することなく、あるバリデータから別のバリデータに資金を移動できます。 残高のすべてをステーキングしようとしています。ステーキング解除や報酬請求にかかるネットワーク手数料をカバーするために、少額を残しておくことをお勧めします。 - TONでステーキングを開始するには、まず任意の金額の送金を行ってください。これにより、ウォレットがアクティブになります。 + TONのステーキングを開始するには、まず自分のアドレスに少額の取引を送信します。これによりウォレットが有効になります。 取引を完了するには、ネットワーク手数料に加えて最大0.2TONが必要になる場合があります。未使用分は返金されます。 この操作を続行するには、ネットワーク手数料に加えて0.2 TONが必要です。残高を補充してください。 TONの準備金が必要です @@ -1214,6 +1219,7 @@ Web3.0対応 続行するには少なくとも%1$sの受信取引が必要です 残高不足 + 承認すると、このスマートコントラクトが今後の取引でトークンを利用できるようになります。 固定レート ネットワークは、あなたがトークンのスワップを承認していることを確認するために、トークン承認手数料を請求します。 より多くのトークンをより良いレートで、ウォレット内にて直接交換します。 @@ -1653,7 +1659,7 @@ 承認を確定する 資産残高に関するテキスト [プレースホルダー] あなたの%sはAaveに預けられています - %s%を獲得 + %1$s%% を獲得 利用可能 現在のAPY 私の資金 @@ -1670,6 +1676,8 @@ 手数料ポリシー ここに説明を入力してください。1〜3行が理想的です。[プレースホルダー] トークン承認が必要 + ネットワーク接続を確認してください + ネットワーク手数料についての情報にアクセスできません アカウントへの入金はすべて自動的にAaveに貸し出されます。 残高は自動的に計算されます いつでも、即座に資金を送信、交換、売却できます。 diff --git a/core/res/src/main/res/values-ru/strings.xml b/core/res/src/main/res/values-ru/strings.xml index 8c66048afe..979bd1a061 100644 --- a/core/res/src/main/res/values-ru/strings.xml +++ b/core/res/src/main/res/values-ru/strings.xml @@ -1298,6 +1298,8 @@ Неверная карта или кольцо выбрана в приложении Tangem Не удалось создать транзакцию из данных Dapp. Код: %s Произошла непредвиденная ошибка. Код ошибки: %d. Попробуйте, пожалуйста, позже. Если проблема будет продолжать возникать — обратитесь в службу поддержки. + Транзакция в несколько шагов + Чтобы успешно обработать запрос, ваша транзакция будет разделена на несколько частей. Для завершения потребуется несколько приложений карты. Нет открытых сессий WalletConnect Упс. Нет сессий. Не удалось создать пару WalletConnect: %1$s @@ -1309,6 +1311,8 @@ Эту карту нельзя использовать с WalletConnect. Сеть не поддерживается. Пожалуйста, выберите другую сеть. Выберите сеть + Транзакция в процессе отправки. Пожалуйста, приложите карту несколько раз для её завершения. + Транзакция в обработке Сессии WalletConnect Подключение к dApps WalletConnect diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml index e12a6bbfa6..1459ffedd9 100644 --- a/core/res/src/main/res/values/strings.xml +++ b/core/res/src/main/res/values/strings.xml @@ -19,7 +19,10 @@ Recover You’re about to recover “%1$s”. Recover account + You have already exceeded the limit of 20 active accounts. Archive one to recover + Can\'t recover account Archived + We couldn’t create account. Please try again later. Account created Archive account Archive @@ -263,6 +266,7 @@ %1$s left Legacy Bitcoin Locked + Locked Wallets Main network month Network fee @@ -313,6 +317,7 @@ Sign Sign and send Skip + Something went wrong Stake Staking Start @@ -926,6 +931,7 @@ Send only %s to this address. Sending any other currency will result in its irreversible loss. Send only %1$s on the %2$s network Transfer funds from any wallet or exchange + Address for rewards Participate Failed to load the information about the referral program. Please try again later. Failed to load the information about the referral program. Error code: %s. Please try again later. @@ -1236,6 +1242,7 @@ Web 3.0 Compatible An incoming transaction of at least %1$s is required to proceed Insufficient funds + By approving, you allow the smart contract to use your tokens in future transactions. Fixed Rate The network will charge a token approval fee to verify that you are authorizing the use of your token for the swap. Exchange more tokens at better rates directly in your wallet. @@ -1454,8 +1461,8 @@ Wrong card or ring selected in Tangem App Failed to create transaction from Dapp data. Code: %s We\'ve encountered unknown error. Error code: %d. If the problem persists — feel free to contact our support - Multiple transactions - You’ll need to tap your Tangem device a few times to complete this process. + Multi-Part Transaction + To process successfully, your transaction will be split into multiple parts. You\'ll need to tap your card several times to complete it. No opened WalletConnect sessions Ooops. No Sessions. Failed to pairing WalletConnect session: %1$s @@ -1467,8 +1474,8 @@ This card can\'t be used to establish WalletConnect session This network is not supported. Please select another network. Select network - We\'re processing the transaction - Sending your funds... + The transaction is being processed. Please tap your card multiple times to complete it. + Transaction in progress WalletConnect Sessions Connect to dApps WalletConnect @@ -1724,7 +1731,7 @@ Confirm approval Text about your money in balance [PLACEHOLDER] Your %s is deposited in Aave - Earn %s% + Earn %1$s%% Available Current APY My Funds @@ -1742,6 +1749,8 @@ Fee policy Write description here. In one, two or three lines will be awesome. [PLACEHOLDER] Some token approve needed + Check your network connection + Network fee info unreachable Every top-up of your account will be lended to Aave automatically. Your balance works automatically Send, swap, or sell your funds instantly, anytime you want. diff --git a/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/network/solana/WcSolanaSignTransactionUseCase.kt b/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/network/solana/WcSolanaSignTransactionUseCase.kt index 2a3d2c624f..89a968a5fd 100644 --- a/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/network/solana/WcSolanaSignTransactionUseCase.kt +++ b/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/network/solana/WcSolanaSignTransactionUseCase.kt @@ -14,6 +14,7 @@ import com.tangem.data.walletconnect.utils.BlockAidVerificationDelegate import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.transaction.usecase.PrepareAndSignUseCase import com.tangem.domain.transaction.usecase.SendLargeSolanaTransactionUseCase +import com.tangem.domain.walletconnect.WcAnalyticEvents.SolanaLargeTransactionStatus import com.tangem.domain.walletconnect.error.parseSendError import com.tangem.domain.walletconnect.model.WcSolanaMethod import com.tangem.domain.walletconnect.usecase.method.BlockAidTransactionCheck @@ -59,10 +60,12 @@ internal class WcSolanaSignTransactionUseCase @AssistedInject constructor( sendLargeSolanaTransactionUseCase(context.session.wallet as UserWallet.Cold, context.network, formattedHash) .fold( ifLeft = { + analytics.send(SolanaLargeTransactionStatus(SolanaLargeTransactionStatus.Status.Failed)) Timber.e(it.toString()) emit(state.toResult(parseSendError(it).left())) }, ifRight = { + analytics.send(SolanaLargeTransactionStatus(SolanaLargeTransactionStatus.Status.Success)) val emptyRespond = ByteArray(0).formatAsSolanaSignature() val respondResult = respondService.respond(rawSdkRequest, emptyRespond) emit(state.toResult(respondResult)) diff --git a/domain/wallet-connect/src/main/kotlin/com/tangem/domain/walletconnect/WcAnalyticEvents.kt b/domain/wallet-connect/src/main/kotlin/com/tangem/domain/walletconnect/WcAnalyticEvents.kt index b7228f2980..1ccecda5d1 100644 --- a/domain/wallet-connect/src/main/kotlin/com/tangem/domain/walletconnect/WcAnalyticEvents.kt +++ b/domain/wallet-connect/src/main/kotlin/com/tangem/domain/walletconnect/WcAnalyticEvents.kt @@ -236,6 +236,29 @@ sealed class WcAnalyticEvents( enum class Source { Domain, SmartContract } } + data class SolanaLargeTransaction( + val dappName: String, + ) : WcAnalyticEvents( + event = "Solana Large Transaction", + params = mapOf( + AnalyticsParam.Key.DAPP_NAME to dappName, + ), + ) + + data class SolanaLargeTransactionStatus( + val status: Status, + ) : WcAnalyticEvents( + event = "Solana Large Transaction Status", + params = mapOf( + AnalyticsParam.Key.STATUS to status.value, + ), + ) { + enum class Status(val value: String) { + Success("Success"), + Failed("Failed"), + } + } + enum class DAppVerificationStatus(val status: String) { Verified("Verified"), Risky("Risky"), diff --git a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/model/WcSendTransactionModel.kt b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/model/WcSendTransactionModel.kt index 99b80940ee..8d36bbe2c6 100644 --- a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/model/WcSendTransactionModel.kt +++ b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/model/WcSendTransactionModel.kt @@ -32,6 +32,7 @@ import com.tangem.domain.transaction.error.SendTransactionError.UserCancelledErr import com.tangem.domain.transaction.usecase.GetFeeUseCase import com.tangem.domain.walletconnect.WcAnalyticEvents import com.tangem.domain.walletconnect.WcAnalyticEvents.SignatureRequestReceived.EmulationStatus +import com.tangem.domain.walletconnect.WcAnalyticEvents.SolanaLargeTransaction import com.tangem.domain.walletconnect.WcRequestUseCaseFactory import com.tangem.domain.walletconnect.model.WcRequestError import com.tangem.domain.walletconnect.model.WcRequestError.Companion.message @@ -143,6 +144,7 @@ internal class WcSendTransactionModel @Inject constructor( wcApproval = useCase as? WcApproval sign = { if (isMultipleSignRequired(useCase)) { + analytics.send(SolanaLargeTransaction(useCase.rawSdkRequest.dAppMetaData.name)) openMultipleTransaction(useCase) } else { useCase.sign() From 423afc9584f30e86ec6267dcba450e5b4b5f1a50 Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 29 Sep 2025 19:07:17 +0300 Subject: [PATCH 10/13] Updated on 2026-08-14 --- .../com/tangem/domain/staking/model/StakingIntegrationID.kt | 4 ++++ .../com/tangem/domain/staking/StakingIntegrationIDTest.kt | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/domain/staking/src/main/java/com/tangem/domain/staking/model/StakingIntegrationID.kt b/domain/staking/src/main/java/com/tangem/domain/staking/model/StakingIntegrationID.kt index d7b1631aeb..435abeeffc 100644 --- a/domain/staking/src/main/java/com/tangem/domain/staking/model/StakingIntegrationID.kt +++ b/domain/staking/src/main/java/com/tangem/domain/staking/model/StakingIntegrationID.kt @@ -110,6 +110,10 @@ sealed interface StakingIntegrationID { val integrationId = blockchain.integrationId ?: return null + if (integrationId is Coin && currencyId.contractAddress != null) { + return null + } + return when (integrationId) { is Coin -> integrationId is EthereumToken -> { diff --git a/domain/staking/src/test/kotlin/com/tangem/domain/staking/StakingIntegrationIDTest.kt b/domain/staking/src/test/kotlin/com/tangem/domain/staking/StakingIntegrationIDTest.kt index 965179516f..74095fb3da 100644 --- a/domain/staking/src/test/kotlin/com/tangem/domain/staking/StakingIntegrationIDTest.kt +++ b/domain/staking/src/test/kotlin/com/tangem/domain/staking/StakingIntegrationIDTest.kt @@ -139,9 +139,13 @@ class StakingIntegrationIDTest { expected = StakingIntegrationID.Coin.Cardano, ), CreateModel( - currencyId = CryptoCurrency.ID.fromValue(value = "coin⟨ETH⟩polygon-ecosystem-token⚓"), + currencyId = CryptoCurrency.ID.fromValue(value = "token⟨ETH⟩polygon-ecosystem-token⚓1234567890"), expected = StakingIntegrationID.EthereumToken.Polygon, ), + CreateModel( + currencyId = CryptoCurrency.ID.fromValue(value = "token⟨SOLANA⟩solana⚓1234567890"), + expected = null, + ), ) } From 5f3d7657bf4c659d323e6f539997f450505c8ace Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 30 Sep 2025 11:54:15 +0300 Subject: [PATCH 11/13] Updated on 2026-08-14 --- app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml index 6f2acb4f09..8b20aae928 100644 --- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -2,4 +2,5 @@ + \ No newline at end of file From b1c53659c6fe8bd42fa5c5607b9cd76b4a5f62ae Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 30 Sep 2025 14:18:18 +0300 Subject: [PATCH 12/13] Updated on 2026-08-14 --- .../handlers/appsflyer/AppsFlyerAnalyticsHandler.kt | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/common/analytics/handlers/appsflyer/AppsFlyerAnalyticsHandler.kt b/app/src/main/java/com/tangem/tap/common/analytics/handlers/appsflyer/AppsFlyerAnalyticsHandler.kt index d14d543384..bd7036b570 100644 --- a/app/src/main/java/com/tangem/tap/common/analytics/handlers/appsflyer/AppsFlyerAnalyticsHandler.kt +++ b/app/src/main/java/com/tangem/tap/common/analytics/handlers/appsflyer/AppsFlyerAnalyticsHandler.kt @@ -23,10 +23,12 @@ class AppsFlyerAnalyticsHandler( } class Builder : AnalyticsHandlerBuilder { - override fun build(data: AnalyticsHandlerBuilder.Data): AnalyticsHandler? = when { - !data.isDebug -> AppsFlyerClient(data.application, data.config.appsFlyerApiKey, data.config.appsAppId) - data.isDebug && data.logConfig.appsflyer -> AppsFlyerLogClient(data.jsonConverter) - else -> null - }?.let { AppsFlyerAnalyticsHandler(it) } + override fun build(data: AnalyticsHandlerBuilder.Data): AnalyticsHandler? = null + // disabled for now until analytics strategy is defined + // when { + // !data.isDebug -> AppsFlyerClient(data.application, data.config.appsFlyerApiKey, data.config.appsAppId) + // data.isDebug && data.logConfig.appsflyer -> AppsFlyerLogClient(data.jsonConverter) + // else -> null + // }?.let { AppsFlyerAnalyticsHandler(it) } } } \ No newline at end of file From f83f30d6fa8162045f40af8471421ed18ddfbcdd Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 30 Sep 2025 11:18:44 +0000 Subject: [PATCH 13/13] Updated on 2026-08-14 --- gradle/tangem_dependencies.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/tangem_dependencies.toml b/gradle/tangem_dependencies.toml index d1e39a0355..5af837553d 100644 --- a/gradle/tangem_dependencies.toml +++ b/gradle/tangem_dependencies.toml @@ -5,9 +5,9 @@ # https://github.com/tangem/tangem-sdk-android/ # https://github.com/tangem/vico -tangemBlockchainSdk = "releases-5.29-1249" +tangemBlockchainSdk = "develop-1248" #tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds -tangemCardSdk = "releases-5.29-565" +tangemCardSdk = "develop-564" #tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^ tangemVico = "2.0.0-alpha.25-tangem12" #tangemVico = "0.0.1" # Keep it! - used for local builds ^