Updated on 2026-08-14

This commit is contained in:
Tangem 2025-07-09 19:34:55 +04:00
parent 16bcc5c593
commit e4d637927a
14 changed files with 48 additions and 181 deletions

View file

@ -39,7 +39,6 @@ import com.tangem.domain.wallets.builder.ColdUserWalletBuilder
import com.tangem.domain.wallets.legacy.UserWalletsListManager
import com.tangem.domain.wallets.repository.WalletsRepository
import com.tangem.features.onboarding.v2.OnboardingV2FeatureToggles
import com.tangem.operations.attestation.OnlineCardVerifier
import com.tangem.tap.common.analytics.handlers.BlockchainExceptionHandler
import com.tangem.tap.common.log.TangemAppLoggerInitializer
import com.tangem.tap.domain.scanCard.CardScanningFeatureToggles
@ -138,8 +137,6 @@ interface ApplicationEntryPoint {
fun getWorkerFactory(): HiltWorkerFactory
fun getOnlineCardVerifier(): OnlineCardVerifier
fun getColdUserWalletBuilderFactory(): ColdUserWalletBuilder.Factory
fun getApiConfigsManager(): ApiConfigsManager

View file

@ -58,7 +58,6 @@ import com.tangem.domain.wallets.builder.ColdUserWalletBuilder
import com.tangem.domain.wallets.legacy.UserWalletsListManager
import com.tangem.domain.wallets.repository.WalletsRepository
import com.tangem.features.onboarding.v2.OnboardingV2FeatureToggles
import com.tangem.operations.attestation.OnlineCardVerifier
import com.tangem.operations.attestation.api.TangemApiServiceSettings
import com.tangem.tap.common.analytics.AnalyticsFactory
import com.tangem.tap.common.analytics.api.AnalyticsHandlerBuilder
@ -78,7 +77,6 @@ import com.tangem.wallet.BuildConfig
import dagger.hilt.EntryPoints
import kotlinx.coroutines.*
import org.rekotlin.Store
import kotlin.collections.set
import com.tangem.tap.domain.walletconnect2.domain.LegacyWalletConnectRepository as WalletConnect2Repository
lateinit var store: Store<AppState>
@ -220,9 +218,6 @@ abstract class TangemApplication : Application(), ImageLoaderFactory, Configurat
.setWorkerFactory(workerFactory)
.build()
private val onlineCardVerifier: OnlineCardVerifier
get() = entryPoint.getOnlineCardVerifier()
private val coldUserWalletBuilderFactory: ColdUserWalletBuilder.Factory
get() = entryPoint.getColdUserWalletBuilderFactory()
@ -367,7 +362,6 @@ abstract class TangemApplication : Application(), ImageLoaderFactory, Configurat
clipboardManager = clipboardManager,
settingsManager = settingsManager,
uiMessageSender = uiMessageSender,
onlineCardVerifier = onlineCardVerifier,
coldUserWalletBuilderFactory = coldUserWalletBuilderFactory,
userTokensResponseStore = userTokensResponseStore,
),

View file

@ -16,16 +16,11 @@ import com.tangem.crypto.bip39.Wordlist
import com.tangem.data.card.sdk.CardSdkOwner
import com.tangem.data.card.sdk.CardSdkProvider
import com.tangem.datasource.api.common.config.ApiConfig
import com.tangem.datasource.api.common.config.ApiEnvironment
import com.tangem.datasource.api.common.config.managers.ApiConfigsManager
import com.tangem.datasource.local.preferences.AppPreferencesStore
import com.tangem.datasource.local.preferences.PreferencesKeys
import com.tangem.datasource.local.preferences.utils.getObjectMap
import com.tangem.datasource.utils.AddHeadersInterceptor
import com.tangem.datasource.utils.RequestHeader
import com.tangem.operations.attestation.api.TangemApiServiceSettings
import com.tangem.sdk.DefaultSessionViewDelegate
import com.tangem.sdk.api.featuretoggles.CardSdkFeatureToggles
import com.tangem.sdk.extensions.*
import com.tangem.sdk.nfc.AndroidNfcAvailabilityProvider
import com.tangem.sdk.nfc.NfcManager
@ -34,13 +29,6 @@ import com.tangem.tap.foregroundActivityObserver
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.info.AppInfoProvider
import com.tangem.utils.version.AppVersionProvider
import com.tangem.wallet.BuildConfig
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.runBlocking
import javax.inject.Inject
import javax.inject.Singleton
@ -55,11 +43,9 @@ import javax.inject.Singleton
internal class DefaultCardSdkProvider @Inject constructor(
private val analyticsExceptionHandler: AnalyticsExceptionHandler,
private val dispatchers: CoroutineDispatcherProvider,
private val cardSdkFeatureToggles: CardSdkFeatureToggles,
private val apiConfigsManager: ApiConfigsManager,
appVersionProvider: AppVersionProvider,
appInfoProvider: AppInfoProvider,
appPreferencesStore: AppPreferencesStore,
) : CardSdkProvider, CardSdkOwner {
private val observer = Observer()
@ -70,27 +56,28 @@ internal class DefaultCardSdkProvider @Inject constructor(
get() = holder?.sdk ?: tryToRegisterWithForegroundActivity()
init {
if (BuildConfig.TESTER_MENU_ENABLED) {
appPreferencesStore.getObjectMap<ApiEnvironment>(PreferencesKeys.apiConfigsEnvironmentKey)
.map {
when (it[ApiConfig.ID.TangemTech.name]) {
ApiEnvironment.DEV,
ApiEnvironment.STAGE,
ApiEnvironment.MOCK,
-> false
ApiEnvironment.PROD,
null,
-> true
}
}
.distinctUntilChanged()
.onEach { isProd ->
holder?.let {
it.sdk.config.isTangemAttestationProdEnv = isProd
}
}
.launchIn(CoroutineScope(SupervisorJob() + dispatchers.main))
}
// TODO: [REDACTED_TASK_KEY] Change API's base URL in CardSDK if API environment is changed
// if (BuildConfig.TESTER_MENU_ENABLED) {
// appPreferencesStore.getObjectMap<ApiEnvironment>(PreferencesKeys.apiConfigsEnvironmentKey)
// .map {
// when (it[ApiConfig.ID.TangemTech.name]) {
// ApiEnvironment.DEV,
// ApiEnvironment.STAGE,
// ApiEnvironment.MOCK,
// -> false
// ApiEnvironment.PROD,
// null,
// -> true
// }
// }
// .distinctUntilChanged()
// .onEach { isProd ->
// holder?.let {
// it.sdk.config.isTangemAttestationProdEnv = isProd
// }
// }
// .launchIn(CoroutineScope(SupervisorJob() + dispatchers.main))
// }
TangemApiServiceSettings.addInterceptors(
AddHeadersInterceptor(
@ -188,10 +175,8 @@ internal class DefaultCardSdkProvider @Inject constructor(
keystoreManager = keystoreManager,
wordlist = Wordlist.getWordlist(activity),
config = config.apply {
isNewOnlineAttestationEnabled = cardSdkFeatureToggles.isNewAttestationEnabled
val apiConfig = apiConfigsManager.getEnvironmentConfig(id = ApiConfig.ID.TangemTech)
isTangemAttestationProdEnv = apiConfig.environment == ApiEnvironment.PROD
tangemApiBaseUrl = apiConfig.baseUrl
},
)

View file

@ -15,10 +15,8 @@ import com.tangem.domain.wallets.repository.WalletsRepository
import com.tangem.domain.wallets.usecase.*
import com.tangem.feature.wallet.presentation.wallet.domain.IsWalletNFTEnabledSyncUseCase
import com.tangem.feature.wallet.presentation.wallet.domain.WalletNameMigrationUseCase
import com.tangem.operations.attestation.OnlineCardVerifier
import com.tangem.features.nft.NFTFeatureToggles
import com.tangem.operations.attestation.CardArtworksProvider
import com.tangem.sdk.api.featuretoggles.CardSdkFeatureToggles
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import dagger.Module
import dagger.Provides
@ -191,16 +189,8 @@ internal object WalletsDomainModule {
@Provides
@Singleton
fun provideGetCardImageUseCase(
onlineCardVerifier: OnlineCardVerifier,
cardArtworksProvider: CardArtworksProvider,
cardSdkFeatureToggles: CardSdkFeatureToggles,
): GetCardImageUseCase {
return GetCardImageUseCase(
verifier = onlineCardVerifier,
cardArtworksProvider = cardArtworksProvider,
cardSdkFeatureToggles = cardSdkFeatureToggles,
)
fun provideGetCardImageUseCase(cardArtworksProvider: CardArtworksProvider): GetCardImageUseCase {
return GetCardImageUseCase(cardArtworksProvider = cardArtworksProvider)
}
@Provides

View file

@ -1,47 +0,0 @@
package com.tangem.tap.domain.extensions
import com.tangem.common.extensions.toHexString
import com.tangem.common.services.Result
import com.tangem.domain.common.TwinCardNumber
import com.tangem.domain.common.getTwinCardNumber
import com.tangem.domain.models.scan.CardDTO
import com.tangem.domain.wallets.models.Artwork
import com.tangem.operations.attestation.CardArtworksProvider
import com.tangem.operations.attestation.OnlineCardVerifier
import com.tangem.operations.attestation.api.models.CardVerifyAndGetInfo
fun CardDTO.signedHashesCount(): Int {
return wallets.sumOf { it.totalSignedHashes ?: 0 }
}
suspend fun CardDTO.getOrLoadCardArtworkUrl(
cardInfo: Result<CardVerifyAndGetInfo.Response.Item>? = null,
onlineCardVerifier: OnlineCardVerifier,
): String {
fun ifAnyError(): String {
return when {
cardId.startsWith(Artwork.SERGIO_CARD_ID) -> Artwork.SERGIO_CARD_URL
cardId.startsWith(Artwork.MARTA_CARD_ID) -> Artwork.MARTA_CARD_URL
else -> {
when (getTwinCardNumber()) {
TwinCardNumber.First -> Artwork.TWIN_CARD_1_URL
TwinCardNumber.Second -> Artwork.TWIN_CARD_2_URL
else -> Artwork.DEFAULT_IMG_URL
}
}
}
}
return when (val cardInfoResult = cardInfo ?: onlineCardVerifier.getCardInfo(cardId, cardPublicKey)) {
is Result.Success -> {
val artworkId = cardInfoResult.data.artwork?.id
if (artworkId.isNullOrEmpty()) {
ifAnyError()
} else {
CardArtworksProvider.getUrlForArtwork(cardId, cardPublicKey.toHexString(), artworkId)
}
}
is Result.Failure -> ifAnyError()
}
}

View file

@ -27,7 +27,6 @@ import com.tangem.tap.common.analytics.events.Settings
import com.tangem.tap.common.extensions.dispatchDialogShow
import com.tangem.tap.common.extensions.dispatchNavigationAction
import com.tangem.tap.common.redux.AppDialog
import com.tangem.tap.domain.extensions.signedHashesCount
import com.tangem.tap.features.details.ui.cardsettings.CardInfo
import com.tangem.tap.features.details.ui.cardsettings.CardSettingsScreenState
import com.tangem.tap.features.details.ui.cardsettings.api.CardSettingsComponent
@ -169,6 +168,8 @@ internal class CardSettingsModel @Inject constructor(
}
}
private fun CardDTO.signedHashesCount(): Int = wallets.sumOf { it.totalSignedHashes ?: 0 }
private fun handleClickingItem(item: CardInfo) {
when (item) {
is CardInfo.ChangeAccessCode -> {

View file

@ -33,7 +33,6 @@ import com.tangem.domain.wallets.legacy.UserWalletsListManager
import com.tangem.domain.wallets.repository.WalletsRepository
import com.tangem.features.onboarding.v2.OnboardingV2FeatureToggles
import com.tangem.operations.attestation.CardArtworksProvider
import com.tangem.operations.attestation.OnlineCardVerifier
import com.tangem.tap.domain.scanCard.CardScanningFeatureToggles
import com.tangem.tap.domain.walletconnect2.domain.LegacyWalletConnectRepository
import com.tangem.tap.domain.walletconnect2.domain.WalletConnectInteractor
@ -75,7 +74,6 @@ data class DaggerGraphState(
val clipboardManager: ClipboardManager? = null,
val settingsManager: SettingsManager? = null,
val uiMessageSender: UiMessageSender? = null,
val onlineCardVerifier: OnlineCardVerifier? = null,
val cardArworksProvider: CardArtworksProvider? = null,
val coldUserWalletBuilderFactory: ColdUserWalletBuilder.Factory? = null,
val userTokensResponseStore: UserTokensResponseStore? = null,

View file

@ -31,14 +31,6 @@
"name": "STAKING_CARDANO_ENABLED",
"version": "undefined"
},
{
"name": "NEW_ARTWORK_LOADING",
"version": "5.25.0"
},
{
"name": "NEW_ATTESTATION_ENABLED",
"version": "5.24.0"
},
{
"name": "WALLET_CONNECT_REDESIGN_ENABLED",
"version": "undefined"

View file

@ -72,6 +72,6 @@ internal class DefaultCardSdkConfigRepository(
}
override fun setTangemApiProdEnvFlag(flag: Boolean) {
sdk.config.isTangemAttestationProdEnv = flag
// TODO: [REDACTED_TASK_KEY] Change API's base URL in CardSDK if API environment is changed
}
}

View file

@ -1,7 +1,6 @@
package com.tangem.domain.wallets.usecase
import com.tangem.common.card.FirmwareVersion
import com.tangem.common.extensions.toHexString
import com.tangem.common.services.Result
import com.tangem.domain.common.TwinCardNumber
import com.tangem.domain.common.TwinsHelper
@ -9,20 +8,16 @@ import com.tangem.domain.models.ArtworkModel
import com.tangem.domain.wallets.models.Artwork
import com.tangem.operations.attestation.ArtworkSize
import com.tangem.operations.attestation.CardArtworksProvider
import com.tangem.operations.attestation.OnlineCardVerifier
import com.tangem.sdk.api.featuretoggles.CardSdkFeatureToggles
/**
* Use case for getting card image url
*
* @property verifier online card verifier
* @property cardArtworksProvider card artworks provider
*
[REDACTED_AUTHOR]
*/
class GetCardImageUseCase(
private val verifier: OnlineCardVerifier,
private val cardArtworksProvider: CardArtworksProvider,
private val cardSdkFeatureToggles: CardSdkFeatureToggles,
) {
/**
@ -38,39 +33,17 @@ class GetCardImageUseCase(
firmwareVersion: FirmwareVersion,
size: ArtworkSize = ArtworkSize.SMALL,
): ArtworkModel {
return if (cardSdkFeatureToggles.isNewArtworkLoadingEnabled) {
val result = cardArtworksProvider.getArtwork(
cardId = cardId,
cardPublicKey = cardPublicKey,
manufacturerName = manufacturerName,
firmwareVersion = firmwareVersion,
size = size,
)
when (result) {
is Result.Failure -> ArtworkModel(null, getFallbackArtworkUrl(cardId))
is Result.Success -> ArtworkModel(result.data, getFallbackArtworkUrl(cardId))
}
} else {
ArtworkModel(null, getLegacyArtwork(cardId, cardPublicKey))
}
}
val result = cardArtworksProvider.getArtwork(
cardId = cardId,
cardPublicKey = cardPublicKey,
manufacturerName = manufacturerName,
firmwareVersion = firmwareVersion,
size = size,
)
private suspend fun getLegacyArtwork(cardId: String, cardPublicKey: ByteArray): String {
return when (val result = verifier.getCardInfo(cardId, cardPublicKey)) {
is Result.Success -> {
val artworkId = result.data.artwork?.id
if (artworkId.isNullOrEmpty()) {
getFallbackArtworkUrl(cardId)
} else {
CardArtworksProvider.getUrlForArtwork(
cardId = cardId,
cardPublicKey = cardPublicKey.toHexString(),
artworkId = artworkId,
)
}
}
is Result.Failure -> getFallbackArtworkUrl(cardId)
return when (result) {
is Result.Failure -> ArtworkModel(null, getFallbackArtworkUrl(cardId))
is Result.Success -> ArtworkModel(result.data, getFallbackArtworkUrl(cardId))
}
}

View file

@ -7,7 +7,7 @@
tangemBlockchainSdk = "develop-1104"
#tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds
tangemCardSdk = "develop-487"
tangemCardSdk = "develop-489"
#tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^
tangemVico = "2.0.0-alpha.25-tangem12"
#tangemVico = "0.0.1" # Keep it! - used for local builds ^

View file

@ -2,7 +2,6 @@ package com.tangem.sdk.api.di
import com.tangem.domain.card.repository.CardSdkConfigRepository
import com.tangem.operations.attestation.CardArtworksProvider
import com.tangem.operations.attestation.OnlineCardVerifier
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
@ -15,13 +14,10 @@ internal object CardSdkModule {
@Provides
@Singleton
fun provideOnlineCardVerifier(): OnlineCardVerifier = OnlineCardVerifier()
@Provides
@Singleton
fun provideCardArtworksProvider(sdkRepository: CardSdkConfigRepository): CardArtworksProvider =
CardArtworksProvider(
sdkRepository.sdk.config.isTangemAttestationProdEnv,
sdkRepository.sdk.secureStorage,
fun provideCardArtworksProvider(sdkRepository: CardSdkConfigRepository): CardArtworksProvider {
return CardArtworksProvider(
tangemApiBaseUrlProvider = { sdkRepository.sdk.config.tangemApiBaseUrl },
secureStorage = sdkRepository.sdk.secureStorage,
)
}
}

View file

@ -5,9 +5,4 @@ package com.tangem.sdk.api.featuretoggles
*
[REDACTED_AUTHOR]
*/
interface CardSdkFeatureToggles {
val isNewAttestationEnabled: Boolean
val isNewArtworkLoadingEnabled: Boolean
}
interface CardSdkFeatureToggles

View file

@ -4,12 +4,5 @@ import com.tangem.core.configtoggle.feature.FeatureTogglesManager
import javax.inject.Inject
internal class DefaultCardSdkFeatureToggles @Inject constructor(
private val featureTogglesManager: FeatureTogglesManager,
) : CardSdkFeatureToggles {
override val isNewAttestationEnabled: Boolean
get() = featureTogglesManager.isFeatureEnabled(name = "NEW_ATTESTATION_ENABLED")
override val isNewArtworkLoadingEnabled: Boolean
get() = featureTogglesManager.isFeatureEnabled(name = "NEW_ARTWORK_LOADING")
}
@Suppress("UnusedPrivateMember") private val featureTogglesManager: FeatureTogglesManager,
) : CardSdkFeatureToggles