From 9a95b49b4a5ee24ba6d779acf1103d4aee80f894 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 21 Jan 2025 17:16:08 +0300 Subject: [PATCH] Updated on 2026-08-14 --- .../tap/data/DefaultVisaAuthTokenStorage.kt | 12 ++-- .../tasks/visa/VisaCardActivationTask.kt | 52 ++++++++------- .../tap/domain/visa/VisaCardScanHandler.kt | 63 +++++++++++-------- .../network/auth/DefaultVisaAuthProvider.kt | 4 +- .../api/common/config/TangemVisa.kt | 9 +-- .../api/common/visa/TangemVisaAuthProvider.kt | 2 +- .../datasource/api/visa/TangemVisaApi.kt | 5 +- .../tangem/datasource/di/ApiConfigsModule.kt | 4 +- .../local/visa/VisaAuthTokenStorage.kt | 4 +- .../managers/ProdApiConfigsManagerTest.kt | 11 +--- .../visa/DefaultVisaActivationRepository.kt | 16 +++-- .../com/tangem/data/visa/di/VisaDataModule.kt | 4 +- .../repository/VisaActivationRepository.kt | 4 ++ 13 files changed, 103 insertions(+), 87 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/data/DefaultVisaAuthTokenStorage.kt b/app/src/main/java/com/tangem/tap/data/DefaultVisaAuthTokenStorage.kt index 7e975e8f02..5adc5fd942 100644 --- a/app/src/main/java/com/tangem/tap/data/DefaultVisaAuthTokenStorage.kt +++ b/app/src/main/java/com/tangem/tap/data/DefaultVisaAuthTokenStorage.kt @@ -33,22 +33,20 @@ internal class DefaultVisaAuthTokenStorage @Inject constructor( private val tokensAdapter = moshi.adapter(VisaAuthTokens::class.java) - override suspend fun store(tokens: VisaAuthTokens) = withContext(dispatcherProvider.io) { + override suspend fun store(cardId: String, tokens: VisaAuthTokens) = withContext(dispatcherProvider.io) { val json = tokensAdapter.toJson(tokens) secureStorage.store( json.encodeToByteArray(throwOnInvalidSequence = true), - VISA_AUTH_TOKENS_KEY, + createKey(cardId), ) } - override suspend fun get(): VisaAuthTokens? = withContext(dispatcherProvider.io) { - secureStorage.get(VISA_AUTH_TOKENS_KEY) + override suspend fun get(cardId: String): VisaAuthTokens? = withContext(dispatcherProvider.io) { + secureStorage.get(createKey(cardId)) ?.decodeToString(throwOnInvalidSequence = true) ?.let(tokensAdapter::fromJson) } - private companion object { - const val VISA_AUTH_TOKENS_KEY = "visa_auth_tokens" - } + private fun createKey(cardId: String): String = "visa_auth_tokens_$cardId" } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/tasks/visa/VisaCardActivationTask.kt b/app/src/main/java/com/tangem/tap/domain/tasks/visa/VisaCardActivationTask.kt index 184e2a3f63..d1efcf68c4 100644 --- a/app/src/main/java/com/tangem/tap/domain/tasks/visa/VisaCardActivationTask.kt +++ b/app/src/main/java/com/tangem/tap/domain/tasks/visa/VisaCardActivationTask.kt @@ -2,6 +2,7 @@ package com.tangem.tap.domain.tasks.visa import com.reown.util.hexToBytes import com.tangem.common.CompletionResult +import com.tangem.common.card.Card import com.tangem.common.core.CardSession import com.tangem.common.core.CardSessionRunnable import com.tangem.common.core.CompletionCallback @@ -36,9 +37,15 @@ class VisaCardActivationTask @AssistedInject constructor( private val otpStorage: VisaOTPStorage, private val visaAuthTokenStorage: VisaAuthTokenStorage, private val visaAuthRepository: VisaAuthRepository, - private val visaActivationRepository: VisaActivationRepository, + private val visaActivationRepositoryFactory: VisaActivationRepository.Factory, ) : CardSessionRunnable { + private class SessionContext( + val visaActivationRepository: VisaActivationRepository, + val card: Card, + val session: CardSession, + ) + override fun run(session: CardSession, callback: CompletionCallback) { coroutineScope.launch { callback(runSuspend(session)) @@ -52,20 +59,27 @@ class VisaCardActivationTask @AssistedInject constructor( return CompletionResult.Failure(TangemSdkError.Underlying(VisaActivationError.WrongCard.message)) } + val visaActivationRepository = visaActivationRepositoryFactory.create(card.cardId) + + val context = SessionContext( + visaActivationRepository = visaActivationRepository, + card = card, + session = session, + ) + return if (challengeToSign != null) { - signAuthorizationChallenge(session, challengeToSign) + context.signAuthorizationChallenge(challengeToSign) } else { val activationOrder = runCatching { visaActivationRepository.getActivationOrderToSign() } .getOrElse { return CompletionResult.Failure(TangemSdkError.Underlying(it.message ?: "")) } - signOrder(session, activationOrder) + context.signOrder(activationOrder) } } - private suspend fun signAuthorizationChallenge( - session: CardSession, + private suspend fun SessionContext.signAuthorizationChallenge( challengeToSign: VisaAuthChallenge.Card, ): CompletionResult { val attestationCommand = AttestCardKeyCommand(challenge = challengeToSign.challenge.hexToBytes()) @@ -78,7 +92,6 @@ class VisaCardActivationTask @AssistedInject constructor( return when (result) { is CompletionResult.Success -> { processSignedAuthorizationChallenge( - session = session, signedChallenge = challengeToSign.toSignedChallenge( signedChallenge = result.data.cardSignature.toHexString(), salt = result.data.salt.toHexString(), @@ -91,8 +104,7 @@ class VisaCardActivationTask @AssistedInject constructor( } } - private suspend fun processSignedAuthorizationChallenge( - session: CardSession, + private suspend fun SessionContext.processSignedAuthorizationChallenge( signedChallenge: VisaAuthSignedChallenge, ): CompletionResult { return coroutineScope { @@ -107,12 +119,14 @@ class VisaCardActivationTask @AssistedInject constructor( otpTaskDeferred.await() - signOrder(session, order) + signOrder(order) } } @Throws(TangemSdkError::class) - private suspend fun getActivationOrderToSign(signedChallenge: VisaAuthSignedChallenge): ActivationOrder { + private suspend fun SessionContext.getActivationOrderToSign( + signedChallenge: VisaAuthSignedChallenge, + ): ActivationOrder { val tokens = runCatching { visaAuthRepository.getAccessTokens(signedChallenge) }.getOrElse { @@ -121,7 +135,7 @@ class VisaCardActivationTask @AssistedInject constructor( ) } - visaAuthTokenStorage.store(tokens) + visaAuthTokenStorage.store(card.cardId, tokens) return visaActivationRepository.getActivationOrderToSign() } @@ -180,11 +194,7 @@ class VisaCardActivationTask @AssistedInject constructor( } } - private suspend fun signOrder( - session: CardSession, - order: ActivationOrder, - ): CompletionResult { - val card = session.environment.card ?: return CompletionResult.Failure(TangemSdkError.MissingPreflightRead()) + private suspend fun SessionContext.signOrder(order: ActivationOrder): CompletionResult { val wallet = card.wallets.firstOrNull() ?: return CompletionResult.Failure(TangemSdkError.MissingPreflightRead()) val task = SignHashCommand(order.hash.hexToBytes(), wallet.publicKey) @@ -197,7 +207,6 @@ class VisaCardActivationTask @AssistedInject constructor( return when (result) { is CompletionResult.Success -> { handleSignedOrder( - session = session, activationOrder = order, response = result.data, ) @@ -208,13 +217,10 @@ class VisaCardActivationTask @AssistedInject constructor( } } - private suspend fun handleSignedOrder( - session: CardSession, + private suspend fun SessionContext.handleSignedOrder( activationOrder: ActivationOrder, response: SignHashResponse, ): CompletionResult { - val card = session.environment.card ?: return CompletionResult.Failure(TangemSdkError.MissingPreflightRead()) - val signedOrder = SignedActivationOrder( activationOrder = activationOrder, signature = response.signature.toHexString(), @@ -232,9 +238,7 @@ class VisaCardActivationTask @AssistedInject constructor( return setupAccessCode(session).map { activationResponse } } - private suspend fun setupAccessCode(session: CardSession): CompletionResult { - val card = session.environment.card ?: return CompletionResult.Failure(TangemSdkError.MissingPreflightRead()) - + private suspend fun SessionContext.setupAccessCode(session: CardSession): CompletionResult { if (card.isAccessCodeSet) { return CompletionResult.Success(Unit) } diff --git a/app/src/main/java/com/tangem/tap/domain/visa/VisaCardScanHandler.kt b/app/src/main/java/com/tangem/tap/domain/visa/VisaCardScanHandler.kt index c231b0ba49..a86f371d93 100644 --- a/app/src/main/java/com/tangem/tap/domain/visa/VisaCardScanHandler.kt +++ b/app/src/main/java/com/tangem/tap/domain/visa/VisaCardScanHandler.kt @@ -1,6 +1,7 @@ package com.tangem.tap.domain.visa import com.tangem.common.CompletionResult +import com.tangem.common.card.Card import com.tangem.common.card.CardWallet import com.tangem.common.core.CardSession import com.tangem.common.core.TangemSdkError @@ -24,10 +25,16 @@ import kotlin.coroutines.resume internal class VisaCardScanHandler @Inject constructor( private val visaAuthRepository: VisaAuthRepository, - private val visaActivationRepository: VisaActivationRepository, + private val visaActivationRepositoryFactory: VisaActivationRepository.Factory, private val visaAuthTokenStorage: VisaAuthTokenStorage, ) { + private class SessionContext( + val visaActivationRepository: VisaActivationRepository, + val card: Card, + val session: CardSession, + ) + suspend fun handleVisaCardScan(session: CardSession): CompletionResult { Timber.i("Attempting to handle Visa card scan") @@ -36,6 +43,14 @@ internal class VisaCardScanHandler @Inject constructor( return CompletionResult.Failure(TangemSdkError.MissingPreflightRead()) } + val visaActivationRepository = visaActivationRepositoryFactory.create(card.cardId) + + val context = SessionContext( + visaActivationRepository = visaActivationRepository, + card = card, + session = session, + ) + val wallet = card.wallets.firstOrNull { it.curve == VisaUtilities.mandatoryCurve } ?: run { val activationInput = VisaActivationInput(card.cardId, card.cardPublicKey, card.isAccessCodeSet) @@ -43,13 +58,10 @@ internal class VisaCardScanHandler @Inject constructor( return CompletionResult.Success(activationStatus) } - return deriveKey(wallet, session) + return context.deriveKey(wallet) } - private suspend fun deriveKey( - wallet: CardWallet, - session: CardSession, - ): CompletionResult { + private suspend fun SessionContext.deriveKey(wallet: CardWallet): CompletionResult { val derivationPath = VisaUtilities.visaDefaultDerivationPath ?: run { Timber.e("Failed to create derivation path while first scan") @@ -64,17 +76,16 @@ internal class VisaCardScanHandler @Inject constructor( continuation.resume(result) } } - return handleDerivationResponse(derivationTaskResult, session) + return handleDerivationResponse(derivationTaskResult) } - private suspend fun handleDerivationResponse( + private suspend fun SessionContext.handleDerivationResponse( result: CompletionResult, - session: CardSession, ): CompletionResult { return when (result) { is CompletionResult.Success -> { Timber.i("Start task for loading challenge for Visa wallet") - handleWalletAuthorization(session) + handleWalletAuthorization() } is CompletionResult.Failure -> { CompletionResult.Failure(result.error) @@ -82,9 +93,8 @@ internal class VisaCardScanHandler @Inject constructor( } } - private suspend fun handleWalletAuthorization(session: CardSession): CompletionResult { + private suspend fun SessionContext.handleWalletAuthorization(): CompletionResult { Timber.i("Started handling authorization using Visa wallet") - val card = session.environment.card ?: return CompletionResult.Failure(TangemSdkError.MissingPreflightRead()) val derivationPath = VisaUtilities.visaDefaultDerivationPath ?: run { Timber.e("Failed to create derivation path while handling wallet authorization") @@ -122,14 +132,12 @@ internal class VisaCardScanHandler @Inject constructor( publicKey = wallet.publicKey, derivationPath = derivationPath, nonce = challengeResponse.challenge, - session = session, ) return when (signChallengeResult) { is CompletionResult.Success -> { Timber.i("Challenge signed with Wallet public key") handleWalletAuthorizationTokens( - session = session, signedChallenge = challengeResponse .toSignedChallenge(signChallengeResult.data.signature.toHexString()), ) @@ -141,27 +149,31 @@ internal class VisaCardScanHandler @Inject constructor( } } - private suspend fun handleWalletAuthorizationTokens( - session: CardSession, + private suspend fun SessionContext.handleWalletAuthorizationTokens( signedChallenge: VisaAuthSignedChallenge, ): CompletionResult { + val card = session.environment.card ?: return CompletionResult.Failure(TangemSdkError.MissingPreflightRead()) + val authorizationTokensResponse = runCatching { visaAuthRepository.getAccessTokens(signedChallenge = signedChallenge) }.getOrElse { Timber.i( "Failed to get Access token for Wallet public key authoziation. Authorizing using Card Pub key", ) - return handleCardAuthorization(session) + return handleCardAuthorization() } - visaAuthTokenStorage.store(authorizationTokensResponse) + visaAuthTokenStorage.store( + cardId = card.cardId, + tokens = authorizationTokensResponse, + ) Timber.i("Authorized using Wallet public key successfully") return CompletionResult.Success(VisaCardActivationStatus.Activated(authorizationTokensResponse)) } - private suspend fun handleCardAuthorization(session: CardSession): CompletionResult { + private suspend fun SessionContext.handleCardAuthorization(): CompletionResult { val card = session.environment.card ?: return CompletionResult.Failure(TangemSdkError.MissingPreflightRead()) Timber.i("Requesting authorization challenge to sign") @@ -178,7 +190,7 @@ internal class VisaCardScanHandler @Inject constructor( Timber.i("Received challenge to sign: ${challengeResponse.challenge}") - val signChallengeResult = signChallengeWithCard(session = session, challenge = challengeResponse.challenge) + val signChallengeResult = signChallengeWithCard(challenge = challengeResponse.challenge) val attestCardKeyResponse = when (signChallengeResult) { is CompletionResult.Success -> { @@ -210,7 +222,10 @@ internal class VisaCardScanHandler @Inject constructor( ) } - visaAuthTokenStorage.store(authorizationTokensResponse) + visaAuthTokenStorage.store( + cardId = card.cardId, + tokens = authorizationTokensResponse, + ) val activationRemoteState = visaActivationRepository.getActivationRemoteState() @@ -239,11 +254,10 @@ internal class VisaCardScanHandler @Inject constructor( ) } - private suspend fun signChallengeWithWallet( + private suspend fun SessionContext.signChallengeWithWallet( publicKey: ByteArray, derivationPath: DerivationPath, nonce: String, - session: CardSession, ): CompletionResult { val signHashCommand = SignHashCommand(publicKey, nonce.toByteArray(), derivationPath) val result = suspendCancellableCoroutine { @@ -262,8 +276,7 @@ internal class VisaCardScanHandler @Inject constructor( } } - private suspend fun signChallengeWithCard( - session: CardSession, + private suspend fun SessionContext.signChallengeWithCard( challenge: String, ): CompletionResult { val signHashCommand = AttestCardKeyCommand(challenge = challenge.toByteArray()) diff --git a/app/src/main/java/com/tangem/tap/network/auth/DefaultVisaAuthProvider.kt b/app/src/main/java/com/tangem/tap/network/auth/DefaultVisaAuthProvider.kt index 6685813017..36aa8bf2de 100644 --- a/app/src/main/java/com/tangem/tap/network/auth/DefaultVisaAuthProvider.kt +++ b/app/src/main/java/com/tangem/tap/network/auth/DefaultVisaAuthProvider.kt @@ -8,7 +8,7 @@ internal class DefaultVisaAuthProvider @Inject constructor( private val authStorage: VisaAuthTokenStorage, ) : TangemVisaAuthProvider { - override suspend fun getAuthHeader(): String { - return authStorage.get()?.accessToken?.let { "Bearer $it" } ?: "Error in the app!" + override suspend fun getAuthHeader(cardId: String): String { + return authStorage.get(cardId)?.accessToken?.let { "Bearer $it" } ?: "Error in the app!" } } \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/common/config/TangemVisa.kt b/core/datasource/src/main/java/com/tangem/datasource/api/common/config/TangemVisa.kt index 2f7ea8a41f..cbc7c36835 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/api/common/config/TangemVisa.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/api/common/config/TangemVisa.kt @@ -1,11 +1,8 @@ package com.tangem.datasource.api.common.config -import com.tangem.datasource.api.common.visa.TangemVisaAuthProvider import com.tangem.utils.ProviderSuspend -internal class TangemVisa( - private val authProvider: TangemVisaAuthProvider, -) : ApiConfig() { +internal class TangemVisa : ApiConfig() { override val defaultEnvironment: ApiEnvironment = ApiEnvironment.PROD @@ -19,7 +16,5 @@ internal class TangemVisa( headers = createHeaders(), ) - private fun createHeaders() = mapOf( - "Authorization" to ProviderSuspend { authProvider.getAuthHeader() }, - ) + private fun createHeaders() = mapOf>() } \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/common/visa/TangemVisaAuthProvider.kt b/core/datasource/src/main/java/com/tangem/datasource/api/common/visa/TangemVisaAuthProvider.kt index 62197282df..1f164d8411 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/api/common/visa/TangemVisaAuthProvider.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/api/common/visa/TangemVisaAuthProvider.kt @@ -2,5 +2,5 @@ package com.tangem.datasource.api.common.visa interface TangemVisaAuthProvider { - suspend fun getAuthHeader(): String + suspend fun getAuthHeader(cardId: String): String } \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/visa/TangemVisaApi.kt b/core/datasource/src/main/java/com/tangem/datasource/api/visa/TangemVisaApi.kt index afdded620a..3e0b010bc8 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/api/visa/TangemVisaApi.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/api/visa/TangemVisaApi.kt @@ -2,9 +2,12 @@ package com.tangem.datasource.api.visa import com.tangem.datasource.api.visa.models.response.CardActivationRemoteStateResponse import retrofit2.http.GET +import retrofit2.http.Header interface TangemVisaApi { @GET("activation-status") - suspend fun getRemoteActivationStatus(): CardActivationRemoteStateResponse + suspend fun getRemoteActivationStatus( + @Header("Authorization") authHeader: String, + ): CardActivationRemoteStateResponse } \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/di/ApiConfigsModule.kt b/core/datasource/src/main/java/com/tangem/datasource/di/ApiConfigsModule.kt index a9576c3042..4f6517e5ff 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/di/ApiConfigsModule.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/di/ApiConfigsModule.kt @@ -5,7 +5,6 @@ import com.tangem.datasource.api.common.config.* import com.tangem.datasource.api.common.config.Express import com.tangem.datasource.api.common.config.StakeKit import com.tangem.datasource.api.common.config.TangemTech -import com.tangem.datasource.api.common.visa.TangemVisaAuthProvider import com.tangem.datasource.local.config.environment.EnvironmentConfigStorage import com.tangem.lib.auth.ExpressAuthProvider import com.tangem.lib.auth.StakeKitAuthProvider @@ -47,6 +46,5 @@ internal object ApiConfigsModule { @Provides @IntoSet - fun provideTangemVisaConfig(tangemVisaAuthProvider: TangemVisaAuthProvider): ApiConfig = - TangemVisa(tangemVisaAuthProvider) + fun provideTangemVisaConfig(): ApiConfig = TangemVisa() } \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/visa/VisaAuthTokenStorage.kt b/core/datasource/src/main/java/com/tangem/datasource/local/visa/VisaAuthTokenStorage.kt index 92ffe1073b..cceb0afdde 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/local/visa/VisaAuthTokenStorage.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/local/visa/VisaAuthTokenStorage.kt @@ -4,7 +4,7 @@ import com.tangem.domain.visa.model.VisaAuthTokens interface VisaAuthTokenStorage { - suspend fun store(tokens: VisaAuthTokens) + suspend fun store(cardId: String, tokens: VisaAuthTokens) - suspend fun get(): VisaAuthTokens? + suspend fun get(cardId: String): VisaAuthTokens? } \ No newline at end of file diff --git a/core/datasource/src/test/kotlin/com/tangem/datasource/api/common/config/managers/ProdApiConfigsManagerTest.kt b/core/datasource/src/test/kotlin/com/tangem/datasource/api/common/config/managers/ProdApiConfigsManagerTest.kt index 5d92d7abd8..5e82b60126 100644 --- a/core/datasource/src/test/kotlin/com/tangem/datasource/api/common/config/managers/ProdApiConfigsManagerTest.kt +++ b/core/datasource/src/test/kotlin/com/tangem/datasource/api/common/config/managers/ProdApiConfigsManagerTest.kt @@ -10,12 +10,10 @@ import com.tangem.datasource.api.common.config.ApiConfig.Companion.EXTERNAL_BUIL import com.tangem.datasource.api.common.config.ApiConfig.Companion.INTERNAL_BUILD_TYPE import com.tangem.datasource.api.common.config.ApiConfig.Companion.MOCKED_BUILD_TYPE import com.tangem.datasource.api.common.config.ApiConfig.Companion.RELEASE_BUILD_TYPE -import com.tangem.datasource.api.common.visa.TangemVisaAuthProvider import com.tangem.lib.auth.ExpressAuthProvider import com.tangem.lib.auth.StakeKitAuthProvider import com.tangem.utils.ProviderSuspend import com.tangem.utils.version.AppVersionProvider -import io.mockk.coEvery import io.mockk.every import io.mockk.mockk import kotlinx.coroutines.runBlocking @@ -31,7 +29,6 @@ private val appVersionProvider = mockk() private val expressAuthProvider = mockk() private val stakeKitAuthProvider = mockk() private val appAuthProvider = mockk() -private val visaAuthProvider = mockk() // Don't forget to add new config !!! private val API_CONFIGS = setOf( @@ -39,7 +36,7 @@ private val API_CONFIGS = setOf( TangemTech(appVersionProvider, appAuthProvider), StakeKit(stakeKitAuthProvider), TangemVisaAuth(), - TangemVisa(visaAuthProvider), + TangemVisa(), ) /** @@ -59,7 +56,6 @@ internal class ProdApiConfigsManagerTest(private val model: Model) { every { stakeKitAuthProvider.getApiKey() } returns STAKE_KIT_API_KEY every { appAuthProvider.getCardId() } returns APP_CARD_ID every { appAuthProvider.getCardPublicKey() } returns APP_CARD_PUBLIC_KEY - coEvery { visaAuthProvider.getAuthHeader() } returns VISA_AUTH_HEADER } @Test @@ -84,7 +80,6 @@ internal class ProdApiConfigsManagerTest(private val model: Model) { const val STAKE_KIT_API_KEY = "stake_kit_api_key" const val APP_CARD_ID = "app_card_id" const val APP_CARD_PUBLIC_KEY = "app_public_key" - const val VISA_AUTH_HEADER = "Bearer visa_auth_header" @JvmStatic @Parameterized.Parameters @@ -198,9 +193,7 @@ internal class ProdApiConfigsManagerTest(private val model: Model) { expected = ApiEnvironmentConfig( environment = ApiEnvironment.PROD, baseUrl = "https://bff.tangem.com/", - headers = mapOf( - "Authorization" to ProviderSuspend { VISA_AUTH_HEADER }, - ), + headers = mapOf(), ), ) } diff --git a/data/visa/src/main/kotlin/com/tangem/data/visa/DefaultVisaActivationRepository.kt b/data/visa/src/main/kotlin/com/tangem/data/visa/DefaultVisaActivationRepository.kt index a5be656c53..17862805b5 100644 --- a/data/visa/src/main/kotlin/com/tangem/data/visa/DefaultVisaActivationRepository.kt +++ b/data/visa/src/main/kotlin/com/tangem/data/visa/DefaultVisaActivationRepository.kt @@ -6,23 +6,29 @@ import com.tangem.domain.visa.model.ActivationOrder import com.tangem.domain.visa.model.VisaActivationRemoteState import com.tangem.domain.visa.repository.VisaActivationRepository import com.tangem.utils.coroutines.CoroutineDispatcherProvider +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import kotlinx.coroutines.withContext -import javax.inject.Inject -import javax.inject.Singleton -@Singleton -internal class DefaultVisaActivationRepository @Inject constructor( +internal class DefaultVisaActivationRepository @AssistedInject constructor( + @Assisted private val cardId: String, private val visaApi: TangemVisaApi, private val dispatcherProvider: CoroutineDispatcherProvider, private val visaActivationStatusConverter: VisaActivationStatusConverter, ) : VisaActivationRepository { override suspend fun getActivationRemoteState(): VisaActivationRemoteState = withContext(dispatcherProvider.io) { - visaActivationStatusConverter.convert(visaApi.getRemoteActivationStatus()) + visaActivationStatusConverter.convert(visaApi.getRemoteActivationStatus(cardId)) // TODO implement refreshing access token if it's expired } override suspend fun getActivationOrderToSign(): ActivationOrder { return ActivationOrder("TODO implement") } + + @AssistedFactory + interface Factory : VisaActivationRepository.Factory { + override fun create(cardId: String): DefaultVisaActivationRepository + } } \ No newline at end of file diff --git a/data/visa/src/main/kotlin/com/tangem/data/visa/di/VisaDataModule.kt b/data/visa/src/main/kotlin/com/tangem/data/visa/di/VisaDataModule.kt index 1ffd8cec35..f1582ade9e 100644 --- a/data/visa/src/main/kotlin/com/tangem/data/visa/di/VisaDataModule.kt +++ b/data/visa/src/main/kotlin/com/tangem/data/visa/di/VisaDataModule.kt @@ -38,5 +38,7 @@ internal interface VisaDataBindsModule { @Binds @Singleton - fun bindVisaActivationRepository(repository: DefaultVisaActivationRepository): VisaActivationRepository + fun bindVisaActivationRepositoryFactory( + repository: DefaultVisaActivationRepository.Factory, + ): VisaActivationRepository.Factory } \ No newline at end of file diff --git a/domain/visa/src/main/kotlin/com/tangem/domain/visa/repository/VisaActivationRepository.kt b/domain/visa/src/main/kotlin/com/tangem/domain/visa/repository/VisaActivationRepository.kt index 8127f921c6..810e422951 100644 --- a/domain/visa/src/main/kotlin/com/tangem/domain/visa/repository/VisaActivationRepository.kt +++ b/domain/visa/src/main/kotlin/com/tangem/domain/visa/repository/VisaActivationRepository.kt @@ -8,4 +8,8 @@ interface VisaActivationRepository { suspend fun getActivationRemoteState(): VisaActivationRemoteState suspend fun getActivationOrderToSign(): ActivationOrder + + interface Factory { + fun create(cardId: String): VisaActivationRepository + } } \ No newline at end of file