diff --git a/app/src/main/java/com/tangem/tap/data/DefaultTangemPayStorage.kt b/app/src/main/java/com/tangem/tap/data/DefaultTangemPayStorage.kt new file mode 100644 index 0000000000..1b9e1d54d7 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/data/DefaultTangemPayStorage.kt @@ -0,0 +1,39 @@ +package com.tangem.tap.data + +import android.content.Context +import com.tangem.datasource.local.visa.TangemPayStorage +import com.tangem.sdk.storage.AndroidSecureStorageV2 +import com.tangem.utils.coroutines.CoroutineDispatcherProvider +import dagger.hilt.android.qualifiers.ApplicationContext +import kotlinx.coroutines.withContext +import javax.inject.Inject +import javax.inject.Singleton + +private const val DEFAULT_KEY = "tangem_pay_default_key" + +@Singleton +internal class DefaultTangemPayStorage @Inject constructor( + @ApplicationContext applicationContext: Context, + private val dispatcherProvider: CoroutineDispatcherProvider, +) : TangemPayStorage { + + private val secureStorage by lazy { + AndroidSecureStorageV2( + appContext = applicationContext, + useStrongBox = false, + name = "tangem_pay_storage", + ) + } + + override suspend fun store(authHeader: String) = withContext(dispatcherProvider.io) { + secureStorage.store(authHeader.encodeToByteArray(throwOnInvalidSequence = true), DEFAULT_KEY) + } + + override suspend fun get(): String? = withContext(dispatcherProvider.io) { + secureStorage.get(DEFAULT_KEY)?.decodeToString(throwOnInvalidSequence = true) + } + + override suspend fun clear() = withContext(dispatcherProvider.io) { + secureStorage.delete(DEFAULT_KEY) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/di/data/VisaStorageModule.kt b/app/src/main/java/com/tangem/tap/di/data/VisaStorageModule.kt index c78909a676..1927963c23 100644 --- a/app/src/main/java/com/tangem/tap/di/data/VisaStorageModule.kt +++ b/app/src/main/java/com/tangem/tap/di/data/VisaStorageModule.kt @@ -1,7 +1,9 @@ package com.tangem.tap.di.data +import com.tangem.datasource.local.visa.TangemPayStorage import com.tangem.datasource.local.visa.VisaAuthTokenStorage import com.tangem.datasource.local.visa.VisaOTPStorage +import com.tangem.tap.data.DefaultTangemPayStorage import com.tangem.tap.data.DefaultVisaAuthTokenStorage import com.tangem.tap.data.DefaultVisaOTPStorage import dagger.Binds @@ -21,4 +23,8 @@ internal interface VisaStorageModule { @Binds @Singleton fun bindVisaOTPStorage(impl: DefaultVisaOTPStorage): VisaOTPStorage + + @Binds + @Singleton + fun bindTangemPayStorage(impl: DefaultTangemPayStorage): TangemPayStorage } \ 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 74ed0d0827..9dd041b2ea 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 @@ -22,7 +22,7 @@ import com.tangem.domain.models.scan.CardDTO import com.tangem.domain.visa.error.VisaActivationError import com.tangem.domain.visa.model.* import com.tangem.domain.visa.repository.VisaActivationRepository -import com.tangem.domain.visa.repository.VisaAuthRepository +import com.tangem.domain.visa.datasource.VisaAuthRemoteDataSource import com.tangem.operations.GenerateOTPCommand import com.tangem.operations.attestation.AttestCardKeyCommand import com.tangem.operations.pins.SetUserCodeCommand @@ -46,7 +46,7 @@ class VisaCardActivationTask @AssistedInject constructor( @Assisted private val coroutineScope: CoroutineScope, private val otpStorage: VisaOTPStorage, private val visaAuthTokenStorage: VisaAuthTokenStorage, - private val visaAuthRepository: VisaAuthRepository, + private val visaAuthRemoteDataSource: VisaAuthRemoteDataSource, private val visaActivationRepositoryFactory: VisaActivationRepository.Factory, ) : CardSessionRunnable { @@ -168,7 +168,7 @@ class VisaCardActivationTask @AssistedInject constructor( signedChallenge: VisaAuthSignedChallenge, cardWalletAddress: String, ): Either = either { - val tokens = visaAuthRepository.getAccessTokens(signedChallenge) + val tokens = visaAuthRemoteDataSource.getAccessTokens(signedChallenge) .getOrElse { raise(it.tangemError) } visaAuthTokenStorage.store(cardId, tokens) 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 c439ee3d5b..d074006981 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 @@ -15,7 +15,7 @@ import com.tangem.domain.visa.error.VisaApiError import com.tangem.domain.visa.error.VisaCardScanError import com.tangem.domain.visa.model.* import com.tangem.domain.visa.repository.VisaActivationRepository -import com.tangem.domain.visa.repository.VisaAuthRepository +import com.tangem.domain.visa.datasource.VisaAuthRemoteDataSource import com.tangem.operations.attestation.AttestCardKeyCommand import com.tangem.operations.attestation.AttestCardKeyResponse import com.tangem.operations.attestation.AttestWalletKeyResponse @@ -26,7 +26,7 @@ import javax.inject.Inject import kotlin.coroutines.resume internal class VisaCardScanHandler @Inject constructor( - private val visaAuthRepository: VisaAuthRepository, + private val visaAuthRemoteDataSource: VisaAuthRemoteDataSource, private val visaActivationRepositoryFactory: VisaActivationRepository.Factory, private val visaAuthTokenStorage: VisaAuthTokenStorage, ) { @@ -83,7 +83,7 @@ internal class VisaCardScanHandler @Inject constructor( Timber.i("Requesting challenge for wallet authorization") - val challengeResponse = visaAuthRepository.getCardWalletAuthChallenge( + val challengeResponse = visaAuthRemoteDataSource.getCardWalletAuthChallenge( cardId = card.cardId, // This is the wallet public key, not the address and it's alright, as the API expects it in this format cardWalletAddress = wallet.publicKey.toHexString(), @@ -122,7 +122,7 @@ internal class VisaCardScanHandler @Inject constructor( cardWalletAddress: String, signedChallenge: VisaAuthSignedChallenge, ): CompletionResult { - val authorizationTokensResponse = visaAuthRepository.getAccessTokens(signedChallenge = signedChallenge) + val authorizationTokensResponse = visaAuthRemoteDataSource.getAccessTokens(signedChallenge = signedChallenge) .getOrElse { Timber.i("Failed to get Access token for Wallet public key authorization.") return if ( @@ -149,7 +149,7 @@ internal class VisaCardScanHandler @Inject constructor( Timber.i("Requesting authorization challenge to sign") - val challengeResponse = visaAuthRepository.getCardAuthChallenge( + val challengeResponse = visaAuthRemoteDataSource.getCardAuthChallenge( cardId = card.cardId, cardPublicKey = card.cardPublicKey.toHexString(), ).getOrElse { @@ -174,7 +174,7 @@ internal class VisaCardScanHandler @Inject constructor( } } - val authorizationTokensResponse = visaAuthRepository.getAccessTokens( + val authorizationTokensResponse = visaAuthRemoteDataSource.getAccessTokens( signedChallenge = challengeResponse.toSignedChallenge( signedChallenge = attestCardKeyResponse.cardSignature.toHexString(), salt = attestCardKeyResponse.salt.toHexString(), diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/pay/TangemPayApi.kt b/core/datasource/src/main/java/com/tangem/datasource/api/pay/TangemPayApi.kt index 8678e1959c..7549cc097f 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/api/pay/TangemPayApi.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/api/pay/TangemPayApi.kt @@ -103,4 +103,7 @@ interface TangemPayApi { @GET("v1/customer/kyc") suspend fun getKycAccess(@Header("Authorization") authHeader: String): ApiResponse + + @GET("v1/customer/me") + suspend fun getCustomerMe(@Header("Authorization") authHeader: String): ApiResponse } \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/pay/models/response/CustomerMeResponse.kt b/core/datasource/src/main/java/com/tangem/datasource/api/pay/models/response/CustomerMeResponse.kt new file mode 100644 index 0000000000..6814d094a9 --- /dev/null +++ b/core/datasource/src/main/java/com/tangem/datasource/api/pay/models/response/CustomerMeResponse.kt @@ -0,0 +1,48 @@ +package com.tangem.datasource.api.pay.models.response + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass + +@JsonClass(generateAdapter = true) +data class CustomerMeResponse( + @Json(name = "result") val result: Result?, + @Json(name = "error") val error: String?, +) { + @JsonClass(generateAdapter = true) + data class Result( + @Json(name = "id") val id: String, + @Json(name = "state") val state: String, + @Json(name = "createdAt") val createdAt: String, + @Json(name = "product_instance") val productInstance: ProductInstance, + @Json(name = "payment_account") val paymentAccount: PaymentAccount, + @Json(name = "kyc") val kyc: Kyc, + ) + + @JsonClass(generateAdapter = true) + data class ProductInstance( + @Json(name = "id") val id: String, + @Json(name = "cid") val cid: String, + @Json(name = "card_id") val cardId: String, + @Json(name = "card_wallet_address") val cardWalletAddress: String, + @Json(name = "status") val status: String, + @Json(name = "updated_at") val updatedAt: String, + @Json(name = "payment_account_id") val paymentAccountId: String, + ) + + @JsonClass(generateAdapter = true) + data class PaymentAccount( + @Json(name = "id") val id: String, + @Json(name = "address") val address: String, + @Json(name = "customer_wallet_address") val customerWalletAddress: String, + ) + + @JsonClass(generateAdapter = true) + data class Kyc( + @Json(name = "id") val id: String, + @Json(name = "provider") val provider: String, + @Json(name = "status") val status: String, + @Json(name = "risk") val risk: String, + @Json(name = "review_answer") val reviewAnswer: String, + @Json(name = "created_at") val createdAt: String, + ) +} \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/visa/TangemPayStorage.kt b/core/datasource/src/main/java/com/tangem/datasource/local/visa/TangemPayStorage.kt new file mode 100644 index 0000000000..d1f8d27e19 --- /dev/null +++ b/core/datasource/src/main/java/com/tangem/datasource/local/visa/TangemPayStorage.kt @@ -0,0 +1,10 @@ +package com.tangem.datasource.local.visa + +interface TangemPayStorage { + + suspend fun store(authHeader: String) + + suspend fun get(): String? + + suspend fun clear() +} \ No newline at end of file diff --git a/data/visa/src/main/kotlin/com/tangem/data/pay/datasource/DefaultTangemPayAuthDataSource.kt b/data/visa/src/main/kotlin/com/tangem/data/pay/datasource/DefaultTangemPayAuthDataSource.kt new file mode 100644 index 0000000000..80ade6e92b --- /dev/null +++ b/data/visa/src/main/kotlin/com/tangem/data/pay/datasource/DefaultTangemPayAuthDataSource.kt @@ -0,0 +1,45 @@ +package com.tangem.data.pay.datasource + +import arrow.core.Either +import arrow.core.raise.either +import com.tangem.common.CompletionResult +import com.tangem.domain.pay.datasource.TangemPayAuthDataSource +import com.tangem.domain.visa.model.VisaDataForApprove +import com.tangem.domain.visa.model.VisaDataToSignByCustomerWallet +import com.tangem.domain.visa.datasource.VisaAuthRemoteDataSource +import com.tangem.sdk.api.TangemSdkManager +import javax.inject.Inject + +internal class DefaultTangemPayAuthDataSource @Inject constructor( + private val visaAuthRemoteDataSource: VisaAuthRemoteDataSource, + private val tangemSdkManager: TangemSdkManager, +) : TangemPayAuthDataSource { + + override suspend fun generateNewAuthHeader(address: String, cardId: String): Either = either { + val challenge = visaAuthRemoteDataSource + .getCustomerWalletAuthChallenge(address) + .mapLeft { IllegalStateException("TangemPay challenge failed. Error code: ${it.errorCode}") } + .bind() + + val signed = tangemSdkManager.visaCustomerWalletApprove( + VisaDataForApprove( + customerWalletCardId = cardId, + targetAddress = address, + dataToSign = VisaDataToSignByCustomerWallet(hashToSign = challenge.challenge), + ), + ).toEither { IllegalStateException("TangemPay signing failed: $it") }.bind() + + visaAuthRemoteDataSource.getTokenWithCustomerWallet( + sessionId = challenge.session.sessionId, + signature = signed.signature, + nonce = signed.dataToSign.hashToSign, + ) + .mapLeft { IllegalStateException("TangemPay token fetch failed. Error code: ${it.errorCode}") } + .bind() + } +} + +private fun CompletionResult.toEither(map: (Throwable) -> Throwable) = when (this) { + is CompletionResult.Success -> Either.Right(data) + is CompletionResult.Failure -> Either.Left(map(error)) +} \ No newline at end of file diff --git a/data/visa/src/main/kotlin/com/tangem/data/pay/di/TangemPayDataModule.kt b/data/visa/src/main/kotlin/com/tangem/data/pay/di/TangemPayDataModule.kt index d0de7d5c31..727e31f796 100644 --- a/data/visa/src/main/kotlin/com/tangem/data/pay/di/TangemPayDataModule.kt +++ b/data/visa/src/main/kotlin/com/tangem/data/pay/di/TangemPayDataModule.kt @@ -1,6 +1,6 @@ package com.tangem.data.pay.di -import com.tangem.data.pay.DefaultKycRepository +import com.tangem.data.pay.repository.DefaultKycRepository import com.tangem.domain.pay.repository.KycRepository import dagger.Binds import dagger.Module diff --git a/data/visa/src/main/kotlin/com/tangem/data/pay/DefaultKycRepository.kt b/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultKycRepository.kt similarity index 60% rename from data/visa/src/main/kotlin/com/tangem/data/pay/DefaultKycRepository.kt rename to data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultKycRepository.kt index cc1a69895e..5ecfd916c5 100644 --- a/data/visa/src/main/kotlin/com/tangem/data/pay/DefaultKycRepository.kt +++ b/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultKycRepository.kt @@ -1,58 +1,48 @@ -package com.tangem.data.pay +package com.tangem.data.pay.repository import arrow.core.Either import com.squareup.moshi.Moshi -import com.tangem.common.map import com.tangem.core.error.UniversalError import com.tangem.datasource.api.common.response.ApiResponseError import com.tangem.datasource.api.common.response.getOrThrow import com.tangem.datasource.api.pay.TangemPayApi import com.tangem.datasource.api.pay.models.response.VisaErrorResponseJsonAdapter import com.tangem.datasource.di.NetworkMoshi +import com.tangem.datasource.local.visa.TangemPayStorage import com.tangem.domain.pay.KycStartInfo +import com.tangem.domain.pay.datasource.TangemPayAuthDataSource import com.tangem.domain.pay.repository.KycRepository import com.tangem.domain.visa.error.VisaApiError -import com.tangem.domain.visa.model.VisaDataForApprove -import com.tangem.domain.visa.model.VisaDataToSignByCustomerWallet -import com.tangem.domain.visa.repository.VisaAuthRepository -import com.tangem.sdk.api.TangemSdkManager import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject class DefaultKycRepository @AssistedInject constructor( @NetworkMoshi moshi: Moshi, private val tangemPayApi: TangemPayApi, - private val visaAuthRepository: VisaAuthRepository, - private val tangemSdkManager: TangemSdkManager, + private val authDataSource: TangemPayAuthDataSource, + private val tangemPayStorage: TangemPayStorage, ) : KycRepository { private val visaErrorAdapter = VisaErrorResponseJsonAdapter(moshi) override suspend fun getKycStartInfo(address: String, cardId: String): Either { - var authHeader = "" - visaAuthRepository.getCustomerWalletAuthChallenge(address).getOrNull()?.let { result -> - tangemSdkManager.visaCustomerWalletApprove( - VisaDataForApprove( - customerWalletCardId = cardId, - targetAddress = address, - dataToSign = VisaDataToSignByCustomerWallet(hashToSign = result.challenge), - ), - ).map { signResult -> - visaAuthRepository.getTokenWithCustomerWallet( - sessionId = result.session.sessionId, - signature = signResult.signature, - nonce = signResult.dataToSign.hashToSign, - ).getOrNull()?.let { authHeader = it } - } - } + val authHeader = authDataSource.generateNewAuthHeader(address, cardId) + .getOrNull() + .takeIf { !it.isNullOrEmpty() } + ?: return Either.Left(VisaApiError.UnknownWithoutCode) + tangemPayStorage.store(authHeader) + return getKycInfo(authHeader) + } + + override suspend fun getKycStartInfo(authHeader: String): Either { + return getKycInfo(authHeader) + } + + private suspend fun getKycInfo(authHeader: String): Either { return request { - authHeader.ifEmpty { error("Cannot get auth header for KYC") } tangemPayApi.getKycAccess(authHeader = authHeader).getOrThrow().result }.map { - KycStartInfo( - token = it.token, - locale = it.locale, - ) + KycStartInfo(token = it.token, locale = it.locale) } } 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 b38b9a82a8..939794afce 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 @@ -18,7 +18,7 @@ import com.tangem.datasource.local.visa.VisaAuthTokenStorage import com.tangem.domain.visa.error.VisaApiError import com.tangem.domain.visa.model.* import com.tangem.domain.visa.repository.VisaActivationRepository -import com.tangem.domain.visa.repository.VisaAuthRepository +import com.tangem.domain.visa.datasource.VisaAuthRemoteDataSource import com.tangem.utils.coroutines.CoroutineDispatcherProvider import dagger.assisted.Assisted import dagger.assisted.AssistedFactory @@ -32,7 +32,7 @@ internal class DefaultVisaActivationRepository @AssistedInject constructor( private val visaApi: TangemPayApi, private val dispatcherProvider: CoroutineDispatcherProvider, private val visaAuthTokenStorage: VisaAuthTokenStorage, - private val visaAuthRepository: VisaAuthRepository, + private val visaAuthRemoteDataSource: VisaAuthRemoteDataSource, private val visaLibLoader: VisaLibLoader, private val apiConfigsManager: ApiConfigsManager, ) : VisaActivationRepository { @@ -194,7 +194,7 @@ internal class DefaultVisaActivationRepository @AssistedInject constructor( } val authTokens = visaAuthTokenStorage.get(visaCardId.cardId) ?: error("Auth tokens are not stored") - val newTokens = visaAuthRepository.refreshAccessTokens(authTokens.refreshToken).getOrElse { + val newTokens = visaAuthRemoteDataSource.refreshAccessTokens(authTokens.refreshToken).getOrElse { return Either.Left(VisaApiError.RefreshTokenExpired) } diff --git a/data/visa/src/main/kotlin/com/tangem/data/visa/DefaultVisaAuthRepository.kt b/data/visa/src/main/kotlin/com/tangem/data/visa/DefaultVisaAuthRemoteDataSource.kt similarity index 97% rename from data/visa/src/main/kotlin/com/tangem/data/visa/DefaultVisaAuthRepository.kt rename to data/visa/src/main/kotlin/com/tangem/data/visa/DefaultVisaAuthRemoteDataSource.kt index 8b3024f1fe..e396978597 100644 --- a/data/visa/src/main/kotlin/com/tangem/data/visa/DefaultVisaAuthRepository.kt +++ b/data/visa/src/main/kotlin/com/tangem/data/visa/DefaultVisaAuthRemoteDataSource.kt @@ -13,17 +13,16 @@ import com.tangem.domain.visa.model.VisaAuthChallenge import com.tangem.domain.visa.model.VisaAuthSession import com.tangem.domain.visa.model.VisaAuthSignedChallenge import com.tangem.domain.visa.model.VisaAuthTokens -import com.tangem.domain.visa.repository.VisaAuthRepository +import com.tangem.domain.visa.datasource.VisaAuthRemoteDataSource import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.coroutines.withContext import javax.inject.Inject -@Suppress("UnusedPrivateMember") -internal class DefaultVisaAuthRepository @Inject constructor( +internal class DefaultVisaAuthRemoteDataSource @Inject constructor( @NetworkMoshi private val moshi: Moshi, private val visaAuthApi: TangemPayApi, private val dispatchers: CoroutineDispatcherProvider, -) : VisaAuthRepository { +) : VisaAuthRemoteDataSource { private val visaErrorAdapter = VisaErrorResponseJsonAdapter(moshi) 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 a173f8c5ea..a5efc3d025 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 @@ -1,10 +1,12 @@ package com.tangem.data.visa.di +import com.tangem.data.pay.datasource.DefaultTangemPayAuthDataSource import com.tangem.data.visa.DefaultVisaActivationRepository -import com.tangem.data.visa.DefaultVisaAuthRepository +import com.tangem.data.visa.DefaultVisaAuthRemoteDataSource import com.tangem.data.visa.MockVisaRepository +import com.tangem.domain.pay.datasource.TangemPayAuthDataSource import com.tangem.domain.visa.repository.VisaActivationRepository -import com.tangem.domain.visa.repository.VisaAuthRepository +import com.tangem.domain.visa.datasource.VisaAuthRemoteDataSource import com.tangem.domain.visa.repository.VisaRepository import dagger.Binds import dagger.Module @@ -18,7 +20,7 @@ internal interface VisaDataModule { @Binds @Singleton - fun bindVisaAuthRepository(repository: DefaultVisaAuthRepository): VisaAuthRepository + fun bindVisaAuthRemoteDataSource(repository: DefaultVisaAuthRemoteDataSource): VisaAuthRemoteDataSource @Binds @Singleton @@ -39,4 +41,8 @@ internal interface VisaDataModule { // Mocked @Binds fun bindVisaRepository(repository: MockVisaRepository): VisaRepository + + @Binds + @Singleton + fun bindTangemPayAuthDataSource(repository: DefaultTangemPayAuthDataSource): TangemPayAuthDataSource } \ No newline at end of file diff --git a/domain/visa/src/main/kotlin/com/tangem/domain/pay/datasource/TangemPayAuthDataSource.kt b/domain/visa/src/main/kotlin/com/tangem/domain/pay/datasource/TangemPayAuthDataSource.kt new file mode 100644 index 0000000000..323d779515 --- /dev/null +++ b/domain/visa/src/main/kotlin/com/tangem/domain/pay/datasource/TangemPayAuthDataSource.kt @@ -0,0 +1,8 @@ +package com.tangem.domain.pay.datasource + +import arrow.core.Either + +interface TangemPayAuthDataSource { + + suspend fun generateNewAuthHeader(address: String, cardId: String): Either +} \ No newline at end of file diff --git a/domain/visa/src/main/kotlin/com/tangem/domain/pay/repository/KycRepository.kt b/domain/visa/src/main/kotlin/com/tangem/domain/pay/repository/KycRepository.kt index 7d46ff2d52..5d4ef99fd3 100644 --- a/domain/visa/src/main/kotlin/com/tangem/domain/pay/repository/KycRepository.kt +++ b/domain/visa/src/main/kotlin/com/tangem/domain/pay/repository/KycRepository.kt @@ -6,8 +6,16 @@ import com.tangem.domain.pay.KycStartInfo interface KycRepository { + /** + * Returns fresh KYC data to start the survey. Used only for first time launch + */ suspend fun getKycStartInfo(address: String, cardId: String): Either + /** + * Returns KYC data to continue the survey. Used when KYC wasn't finished by the user + */ + suspend fun getKycStartInfo(authHeader: String): Either + interface Factory { fun create(): KycRepository } diff --git a/domain/visa/src/main/kotlin/com/tangem/domain/visa/repository/VisaAuthRepository.kt b/domain/visa/src/main/kotlin/com/tangem/domain/visa/datasource/VisaAuthRemoteDataSource.kt similarity index 93% rename from domain/visa/src/main/kotlin/com/tangem/domain/visa/repository/VisaAuthRepository.kt rename to domain/visa/src/main/kotlin/com/tangem/domain/visa/datasource/VisaAuthRemoteDataSource.kt index 098ca44c00..ebec77de6b 100644 --- a/domain/visa/src/main/kotlin/com/tangem/domain/visa/repository/VisaAuthRepository.kt +++ b/domain/visa/src/main/kotlin/com/tangem/domain/visa/datasource/VisaAuthRemoteDataSource.kt @@ -1,4 +1,4 @@ -package com.tangem.domain.visa.repository +package com.tangem.domain.visa.datasource import arrow.core.Either import com.tangem.domain.visa.error.VisaApiError @@ -6,7 +6,7 @@ import com.tangem.domain.visa.model.VisaAuthChallenge import com.tangem.domain.visa.model.VisaAuthSignedChallenge import com.tangem.domain.visa.model.VisaAuthTokens -interface VisaAuthRepository { +interface VisaAuthRemoteDataSource { suspend fun getCardAuthChallenge( cardId: String, diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/visa/impl/child/accesscode/model/OnboardingVisaAccessCodeModel.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/visa/impl/child/accesscode/model/OnboardingVisaAccessCodeModel.kt index 15c3b08a41..b80bb62fda 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/visa/impl/child/accesscode/model/OnboardingVisaAccessCodeModel.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/visa/impl/child/accesscode/model/OnboardingVisaAccessCodeModel.kt @@ -18,7 +18,7 @@ import com.tangem.domain.visa.model.VisaCardActivationStatus import com.tangem.domain.visa.model.VisaCardId import com.tangem.domain.visa.model.VisaCustomerWalletDataToSignRequest import com.tangem.domain.visa.repository.VisaActivationRepository -import com.tangem.domain.visa.repository.VisaAuthRepository +import com.tangem.domain.visa.datasource.VisaAuthRemoteDataSource import com.tangem.features.onboarding.v2.visa.impl.child.accesscode.OnboardingVisaAccessCodeComponent import com.tangem.features.onboarding.v2.visa.impl.child.accesscode.ui.state.OnboardingVisaAccessCodeUM import com.tangem.features.onboarding.v2.visa.impl.child.welcome.model.analytics.OnboardingVisaAnalyticsEvent @@ -44,7 +44,7 @@ internal class OnboardingVisaAccessCodeModel @Inject constructor( override val dispatchers: CoroutineDispatcherProvider, @Suppress("UnusedPrivateMember") private val tangemSdkManager: TangemSdkManager, - private val visaAuthRepository: VisaAuthRepository, + private val visaAuthRemoteDataSource: VisaAuthRemoteDataSource, private val uiMessageSender: UiMessageSender, private val analyticsEventsHandler: AnalyticsEventHandler, ) : Model() { @@ -155,7 +155,7 @@ internal class OnboardingVisaAccessCodeModel @Inject constructor( loading(true) modelScope.launch { - val challengeToSign = visaAuthRepository.getCardAuthChallenge( + val challengeToSign = visaAuthRemoteDataSource.getCardAuthChallenge( cardId = activationInput.cardId, cardPublicKey = activationInput.cardPublicKey, ).getOrElse { diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/visa/impl/child/inprogress/model/OnboardingVisaInProgressModel.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/visa/impl/child/inprogress/model/OnboardingVisaInProgressModel.kt index e517a628cb..1786357959 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/visa/impl/child/inprogress/model/OnboardingVisaInProgressModel.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/visa/impl/child/inprogress/model/OnboardingVisaInProgressModel.kt @@ -18,7 +18,7 @@ import com.tangem.domain.visa.model.VisaAuthTokens import com.tangem.domain.visa.model.VisaCardActivationStatus import com.tangem.domain.visa.model.VisaCardId import com.tangem.domain.visa.repository.VisaActivationRepository -import com.tangem.domain.visa.repository.VisaAuthRepository +import com.tangem.domain.visa.datasource.VisaAuthRemoteDataSource import com.tangem.domain.wallets.builder.ColdUserWalletBuilder import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.wallets.usecase.SaveWalletUseCase @@ -42,7 +42,7 @@ internal class OnboardingVisaInProgressModel @Inject constructor( paramsContainer: ParamsContainer, visaActivationRepositoryFactory: VisaActivationRepository.Factory, override val dispatchers: CoroutineDispatcherProvider, - private val visaAuthRepository: VisaAuthRepository, + private val visaAuthRemoteDataSource: VisaAuthRemoteDataSource, private val visaAuthTokenStorage: VisaAuthTokenStorage, private val otpStorage: VisaOTPStorage, private val coldUserWalletBuilderFactory: ColdUserWalletBuilder.Factory, @@ -166,7 +166,7 @@ internal class OnboardingVisaInProgressModel @Inject constructor( val authTokens = visaAuthTokenStorage.get(params.scanResponse.card.cardId) ?: error("Auth tokens are not found. This should not happen.") - val newTokens = visaAuthRepository.exchangeAccessToken(authTokens) + val newTokens = visaAuthRemoteDataSource.exchangeAccessToken(authTokens) .getOrElse { uiMessageSender.showErrorDialog(it) return