Updated on 2026-08-14
This commit is contained in:
parent
d748cb7a81
commit
2070f1d21c
4 changed files with 39 additions and 148 deletions
|
|
@ -1,15 +1,9 @@
|
||||||
package com.tangem.tap.di
|
package com.tangem.tap.di
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
import com.tangem.core.analytics.api.AnalyticsErrorHandler
|
||||||
import com.tangem.core.analytics.api.AnalyticsExceptionHandler
|
|
||||||
import com.tangem.core.decompose.di.GlobalUiMessageSender
|
|
||||||
import com.tangem.core.decompose.ui.UiMessageSender
|
|
||||||
import com.tangem.core.navigation.finisher.AppFinisher
|
|
||||||
import com.tangem.domain.card.BuildConfig
|
import com.tangem.domain.card.BuildConfig
|
||||||
import com.tangem.domain.card.repository.CardSdkConfigRepository
|
import com.tangem.domain.card.repository.CardSdkConfigRepository
|
||||||
import com.tangem.utils.coroutines.AppCoroutineScope
|
|
||||||
import com.tangem.domain.feedback.SendFeedbackEmailUseCase
|
|
||||||
import com.tangem.features.onboarding.v2.OnboardingV2FeatureToggles
|
import com.tangem.features.onboarding.v2.OnboardingV2FeatureToggles
|
||||||
import com.tangem.sdk.api.TangemSdkManager
|
import com.tangem.sdk.api.TangemSdkManager
|
||||||
import com.tangem.tap.domain.sdk.impl.DefaultTangemSdkManager
|
import com.tangem.tap.domain.sdk.impl.DefaultTangemSdkManager
|
||||||
|
|
@ -38,13 +32,8 @@ internal class TangemSdkManagerModule {
|
||||||
visaCardActivationTaskFactory: VisaCardActivationTask.Factory,
|
visaCardActivationTaskFactory: VisaCardActivationTask.Factory,
|
||||||
tangemPayChallengeTaskFactory: TangemPayGenerateAddressAndSignChallengeTask.Factory,
|
tangemPayChallengeTaskFactory: TangemPayGenerateAddressAndSignChallengeTask.Factory,
|
||||||
onboardingV2FeatureToggles: OnboardingV2FeatureToggles,
|
onboardingV2FeatureToggles: OnboardingV2FeatureToggles,
|
||||||
@GlobalUiMessageSender uiMessageSender: UiMessageSender,
|
|
||||||
appFinisher: AppFinisher,
|
|
||||||
sendFeedbackEmailUseCase: SendFeedbackEmailUseCase,
|
|
||||||
analyticsExceptionHandler: AnalyticsExceptionHandler,
|
|
||||||
blockchainToDeriveFinder: BlockchainToDeriveFinder,
|
blockchainToDeriveFinder: BlockchainToDeriveFinder,
|
||||||
analyticsEventHandler: AnalyticsEventHandler,
|
analyticsErrorHandler: AnalyticsErrorHandler,
|
||||||
appScope: AppCoroutineScope,
|
|
||||||
): TangemSdkManager {
|
): TangemSdkManager {
|
||||||
return if (BuildConfig.MOCK_DATA_SOURCE) {
|
return if (BuildConfig.MOCK_DATA_SOURCE) {
|
||||||
MockTangemSdkManager(resources = context.resources)
|
MockTangemSdkManager(resources = context.resources)
|
||||||
|
|
@ -56,13 +45,8 @@ internal class TangemSdkManagerModule {
|
||||||
visaCardActivationTaskFactory = visaCardActivationTaskFactory,
|
visaCardActivationTaskFactory = visaCardActivationTaskFactory,
|
||||||
tangemPayChallengeTaskFactory = tangemPayChallengeTaskFactory,
|
tangemPayChallengeTaskFactory = tangemPayChallengeTaskFactory,
|
||||||
onboardingV2FeatureToggles = onboardingV2FeatureToggles,
|
onboardingV2FeatureToggles = onboardingV2FeatureToggles,
|
||||||
uiMessageSender = uiMessageSender,
|
|
||||||
appFinisher = appFinisher,
|
|
||||||
sendFeedbackEmailUseCase = sendFeedbackEmailUseCase,
|
|
||||||
analyticsExceptionHandler = analyticsExceptionHandler,
|
|
||||||
blockchainToDeriveFinder = blockchainToDeriveFinder,
|
blockchainToDeriveFinder = blockchainToDeriveFinder,
|
||||||
analyticsEventHandler = analyticsEventHandler,
|
analyticsErrorHandler = analyticsErrorHandler,
|
||||||
coroutineScope = appScope,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,9 @@ import androidx.annotation.StringRes
|
||||||
import arrow.core.Either
|
import arrow.core.Either
|
||||||
import arrow.core.left
|
import arrow.core.left
|
||||||
import arrow.core.right
|
import arrow.core.right
|
||||||
import com.tangem.Log
|
|
||||||
import com.tangem.Message
|
import com.tangem.Message
|
||||||
import com.tangem.TangemSdk
|
import com.tangem.TangemSdk
|
||||||
import com.tangem.common.*
|
import com.tangem.common.*
|
||||||
import com.tangem.common.authentication.AuthenticationManager
|
|
||||||
import com.tangem.common.authentication.keystore.KeystoreManager
|
import com.tangem.common.authentication.keystore.KeystoreManager
|
||||||
import com.tangem.common.core.*
|
import com.tangem.common.core.*
|
||||||
import com.tangem.common.extensions.ByteArrayKey
|
import com.tangem.common.extensions.ByteArrayKey
|
||||||
|
|
@ -18,25 +16,14 @@ import com.tangem.common.extensions.hexToBytes
|
||||||
import com.tangem.common.services.secure.SecureStorage
|
import com.tangem.common.services.secure.SecureStorage
|
||||||
import com.tangem.common.usersCode.UserCodeRepository
|
import com.tangem.common.usersCode.UserCodeRepository
|
||||||
import com.tangem.core.analytics.Analytics
|
import com.tangem.core.analytics.Analytics
|
||||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
import com.tangem.core.analytics.api.AnalyticsErrorHandler
|
||||||
import com.tangem.core.analytics.api.AnalyticsExceptionHandler
|
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||||
import com.tangem.core.analytics.models.AnalyticsParam
|
|
||||||
import com.tangem.core.analytics.models.Basic
|
|
||||||
import com.tangem.core.analytics.models.ExceptionAnalyticsEvent
|
|
||||||
import com.tangem.core.decompose.ui.UiMessageSender
|
|
||||||
import com.tangem.core.navigation.finisher.AppFinisher
|
|
||||||
import com.tangem.core.res.getStringSafe
|
import com.tangem.core.res.getStringSafe
|
||||||
import com.tangem.core.ui.extensions.resourceReference
|
|
||||||
import com.tangem.core.ui.message.DialogMessage
|
|
||||||
import com.tangem.core.ui.message.EventMessageAction
|
|
||||||
import com.tangem.crypto.bip39.DefaultMnemonic
|
import com.tangem.crypto.bip39.DefaultMnemonic
|
||||||
import com.tangem.crypto.hdWallet.DerivationPath
|
import com.tangem.crypto.hdWallet.DerivationPath
|
||||||
import com.tangem.crypto.hdWallet.bip32.ExtendedPublicKey
|
import com.tangem.crypto.hdWallet.bip32.ExtendedPublicKey
|
||||||
import com.tangem.domain.card.common.util.cardTypesResolver
|
import com.tangem.domain.card.common.util.cardTypesResolver
|
||||||
import com.tangem.domain.card.repository.CardSdkConfigRepository
|
import com.tangem.domain.card.repository.CardSdkConfigRepository
|
||||||
import com.tangem.utils.coroutines.AppCoroutineScope
|
|
||||||
import com.tangem.domain.feedback.SendFeedbackEmailUseCase
|
|
||||||
import com.tangem.domain.feedback.models.FeedbackEmailType
|
|
||||||
import com.tangem.domain.models.scan.CardDTO
|
import com.tangem.domain.models.scan.CardDTO
|
||||||
import com.tangem.domain.models.scan.ScanResponse
|
import com.tangem.domain.models.scan.ScanResponse
|
||||||
import com.tangem.domain.models.wallet.UserWalletId
|
import com.tangem.domain.models.wallet.UserWalletId
|
||||||
|
|
@ -67,9 +54,10 @@ import com.tangem.tap.domain.twins.CreateSecondTwinWalletTask
|
||||||
import com.tangem.tap.domain.twins.FinalizeTwinTask
|
import com.tangem.tap.domain.twins.FinalizeTwinTask
|
||||||
import com.tangem.tap.domain.visa.VisaCardScanHandler
|
import com.tangem.tap.domain.visa.VisaCardScanHandler
|
||||||
import com.tangem.wallet.R
|
import com.tangem.wallet.R
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.coroutineScope
|
||||||
import kotlinx.coroutines.sync.withLock
|
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
import kotlin.coroutines.resume
|
import kotlin.coroutines.resume
|
||||||
|
|
||||||
@Suppress("TooManyFunctions", "LargeClass", "LongParameterList")
|
@Suppress("TooManyFunctions", "LargeClass", "LongParameterList")
|
||||||
|
|
@ -80,17 +68,10 @@ internal class DefaultTangemSdkManager(
|
||||||
private val visaCardActivationTaskFactory: VisaCardActivationTask.Factory,
|
private val visaCardActivationTaskFactory: VisaCardActivationTask.Factory,
|
||||||
private val tangemPayChallengeTaskFactory: TangemPayGenerateAddressAndSignChallengeTask.Factory,
|
private val tangemPayChallengeTaskFactory: TangemPayGenerateAddressAndSignChallengeTask.Factory,
|
||||||
private val onboardingV2FeatureToggles: OnboardingV2FeatureToggles,
|
private val onboardingV2FeatureToggles: OnboardingV2FeatureToggles,
|
||||||
private val uiMessageSender: UiMessageSender,
|
|
||||||
private val appFinisher: AppFinisher,
|
|
||||||
private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase,
|
|
||||||
private val analyticsExceptionHandler: AnalyticsExceptionHandler,
|
|
||||||
private val blockchainToDeriveFinder: BlockchainToDeriveFinder,
|
private val blockchainToDeriveFinder: BlockchainToDeriveFinder,
|
||||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
private val analyticsErrorHandler: AnalyticsErrorHandler,
|
||||||
private val coroutineScope: AppCoroutineScope,
|
|
||||||
) : TangemSdkManager {
|
) : TangemSdkManager {
|
||||||
|
|
||||||
private val awaitInitializationMutex = Mutex()
|
|
||||||
|
|
||||||
private val tangemSdk: TangemSdk
|
private val tangemSdk: TangemSdk
|
||||||
get() = cardSdkConfigRepository.sdk
|
get() = cardSdkConfigRepository.sdk
|
||||||
|
|
||||||
|
|
@ -101,10 +82,32 @@ internal class DefaultTangemSdkManager(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
override val needEnrollBiometrics: Boolean
|
override val needEnrollBiometrics: Boolean
|
||||||
get() = tangemSdk.authenticationManager.needEnrollBiometrics
|
get() {
|
||||||
|
val isNeedEnrollBiometrics = tangemSdk.authenticationManager.needEnrollBiometrics
|
||||||
|
if (isNeedEnrollBiometrics) {
|
||||||
|
analyticsErrorHandler.sendErrorEvent(
|
||||||
|
AnalyticsEvent(
|
||||||
|
category = "TangemSdkManager",
|
||||||
|
event = "needEnrollBiometrics",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return isNeedEnrollBiometrics
|
||||||
|
}
|
||||||
|
|
||||||
override val canUseBiometry: Boolean
|
override val canUseBiometry: Boolean
|
||||||
get() = tangemSdk.authenticationManager.canAuthenticate || needEnrollBiometrics
|
get() {
|
||||||
|
val isCanUseBiometry = tangemSdk.authenticationManager.canAuthenticate || needEnrollBiometrics
|
||||||
|
if (!isCanUseBiometry) {
|
||||||
|
analyticsErrorHandler.sendErrorEvent(
|
||||||
|
AnalyticsEvent(
|
||||||
|
category = "TangemSdkManager",
|
||||||
|
event = "cantUseBiometry",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return isCanUseBiometry
|
||||||
|
}
|
||||||
|
|
||||||
override val keystoreManager: KeystoreManager
|
override val keystoreManager: KeystoreManager
|
||||||
get() = tangemSdk.keystoreManager
|
get() = tangemSdk.keystoreManager
|
||||||
|
|
@ -116,49 +119,11 @@ internal class DefaultTangemSdkManager(
|
||||||
get() = tangemSdk.config.userCodeRequestPolicy
|
get() = tangemSdk.config.userCodeRequestPolicy
|
||||||
|
|
||||||
override suspend fun checkNeedEnrollBiometrics(awaitInitialization: Boolean): Boolean {
|
override suspend fun checkNeedEnrollBiometrics(awaitInitialization: Boolean): Boolean {
|
||||||
return try {
|
return needEnrollBiometrics
|
||||||
needEnrollBiometrics
|
|
||||||
} catch (e: TangemSdkError.AuthenticationNotInitialized) {
|
|
||||||
Log.error {
|
|
||||||
"Trying to access `needEnrollBiometrics` flag when authentication manager is not initialized: " +
|
|
||||||
if (awaitInitialization) "awaiting initialization" else "failing"
|
|
||||||
}
|
|
||||||
|
|
||||||
if (awaitInitialization) {
|
|
||||||
val manager = awaitAuthenticationManagerInitialization()
|
|
||||||
|
|
||||||
if (manager.isInitialized) {
|
|
||||||
manager.needEnrollBiometrics
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw e
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun checkCanUseBiometry(awaitInitialization: Boolean): Boolean {
|
override suspend fun checkCanUseBiometry(awaitInitialization: Boolean): Boolean {
|
||||||
return try {
|
return canUseBiometry
|
||||||
canUseBiometry
|
|
||||||
} catch (e: TangemSdkError.AuthenticationNotInitialized) {
|
|
||||||
Log.error {
|
|
||||||
"Trying to access `canUseBiometry` flag when authentication manager is not initialized: " +
|
|
||||||
if (awaitInitialization) "awaiting initialization" else "failing"
|
|
||||||
}
|
|
||||||
|
|
||||||
if (awaitInitialization) {
|
|
||||||
val manager = awaitAuthenticationManagerInitialization()
|
|
||||||
|
|
||||||
if (manager.isInitialized) {
|
|
||||||
manager.canAuthenticate || manager.needEnrollBiometrics
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw e
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun scanProduct(
|
override suspend fun scanProduct(
|
||||||
|
|
@ -432,59 +397,6 @@ internal class DefaultTangemSdkManager(
|
||||||
tangemSdk.config.userCodeRequestPolicy = policy
|
tangemSdk.config.userCodeRequestPolicy = policy
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun awaitAuthenticationManagerInitialization(): AuthenticationManager {
|
|
||||||
return awaitInitializationMutex.withLock {
|
|
||||||
var attemps = 0
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (tangemSdk.authenticationManager.isInitialized) {
|
|
||||||
break
|
|
||||||
} else {
|
|
||||||
if (attemps++ >= MAX_INITIALIZE_ATTEMPTS) {
|
|
||||||
analyticsExceptionHandler.sendException(
|
|
||||||
ExceptionAnalyticsEvent(
|
|
||||||
exception = IllegalStateException(
|
|
||||||
"Can't initialize authentication manager after $MAX_INITIALIZE_ATTEMPTS attempts",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
showAlert()
|
|
||||||
break
|
|
||||||
} else {
|
|
||||||
delay(timeMillis = 400)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (true)
|
|
||||||
|
|
||||||
tangemSdk.authenticationManager
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun showAlert() {
|
|
||||||
uiMessageSender.send(
|
|
||||||
message = DialogMessage(
|
|
||||||
message = resourceReference(id = R.string.alert_authentication_error_message),
|
|
||||||
title = resourceReference(id = R.string.alert_authentication_error_title),
|
|
||||||
isDismissable = false,
|
|
||||||
dismissOnFirstAction = false,
|
|
||||||
firstActionBuilder = {
|
|
||||||
EventMessageAction(
|
|
||||||
title = resourceReference(R.string.alert_button_request_support),
|
|
||||||
onClick = {
|
|
||||||
coroutineScope.launch {
|
|
||||||
analyticsEventHandler.send(
|
|
||||||
Basic.ButtonSupport(source = AnalyticsParam.ScreensSources.SignIn),
|
|
||||||
)
|
|
||||||
sendFeedbackEmailUseCase(FeedbackEmailType.BiometricsAuthenticationFailed)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
},
|
|
||||||
secondActionBuilder = { cancelAction(onClick = appFinisher::finish) },
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// region Twin-specific
|
// region Twin-specific
|
||||||
|
|
||||||
override suspend fun createFirstTwinWallet(
|
override suspend fun createFirstTwinWallet(
|
||||||
|
|
@ -624,8 +536,4 @@ internal class DefaultTangemSdkManager(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
companion object {
|
|
||||||
private const val MAX_INITIALIZE_ATTEMPTS = 10
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
@ -229,7 +229,6 @@ class DefaultHotWalletAccessor @Inject constructor(
|
||||||
this is TangemSdkError.AuthenticationLockout ||
|
this is TangemSdkError.AuthenticationLockout ||
|
||||||
this is TangemSdkError.AuthenticationUnavailable ||
|
this is TangemSdkError.AuthenticationUnavailable ||
|
||||||
this is TangemSdkError.AuthenticationAlreadyInProgress ||
|
this is TangemSdkError.AuthenticationAlreadyInProgress ||
|
||||||
this is TangemSdkError.AuthenticationNotInitialized ||
|
|
||||||
this is TangemSdkError.AuthenticationPermanentLockout
|
this is TangemSdkError.AuthenticationPermanentLockout
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,13 @@
|
||||||
# https://github.com/tangem/tangem-sdk-android/
|
# https://github.com/tangem/tangem-sdk-android/
|
||||||
# https://github.com/tangem/vico
|
# https://github.com/tangem/vico
|
||||||
|
|
||||||
tangemBlockchainSdk = "develop-1447"
|
tangemBlockchainSdk = "develop-1454"
|
||||||
#tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds
|
#tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds
|
||||||
tangemCardSdk = "develop-582"
|
tangemCardSdk = "develop-598"
|
||||||
#tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^
|
#tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^
|
||||||
tangemVico = "2.0.0-alpha.25-tangem12"
|
tangemVico = "2.0.0-alpha.25-tangem12"
|
||||||
#tangemVico = "0.0.1" # Keep it! - used for local builds ^
|
#tangemVico = "0.0.1" # Keep it! - used for local builds ^
|
||||||
tangemHotSdk = "develop-547"
|
tangemHotSdk = "develop-549"
|
||||||
#tangemHotSdk = "0.0.1" # Keep it! - used for local builds ^
|
#tangemHotSdk = "0.0.1" # Keep it! - used for local builds ^
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue