Updated on 2026-08-14

This commit is contained in:
Tangem 2025-06-26 15:05:52 +03:00
parent ebb5b5830e
commit d1c13037e0
42 changed files with 246 additions and 80 deletions

View file

@ -0,0 +1,70 @@
package com.tangem.data.pay
import arrow.core.Either
import com.squareup.moshi.Moshi
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.domain.pay.KycStartInfo
import com.tangem.domain.pay.repository.KycRepository
import com.tangem.domain.visa.error.VisaApiError
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlinx.coroutines.withContext
@Suppress("UnusedPrivateMember")
class DefaultKycRepository @AssistedInject constructor(
@Assisted userWalletId: UserWalletId,
@NetworkMoshi moshi: Moshi,
private val tangemPayApi: TangemPayApi,
private val dispatcherProvider: CoroutineDispatcherProvider,
) : KycRepository {
private val visaErrorAdapter = VisaErrorResponseJsonAdapter(moshi)
override suspend fun getKycStartInfo(): Either<UniversalError, KycStartInfo> = withContext(dispatcherProvider.io) {
val authTokenForSpecificWallet = "get from userWalletId"
request {
tangemPayApi.getKycAccess(
authHeader = authTokenForSpecificWallet,
).getOrThrow().result
}.map {
KycStartInfo(
token = it.token,
locale = it.locale,
)
}
}
private suspend fun <T : Any> request(requestBlock: suspend () -> T): Either<VisaApiError, T> {
return runCatching {
Either.Right(requestBlock())
}.getOrElse { responseError ->
if (responseError is ApiResponseError.HttpException &&
responseError.errorBody != null
) {
return runCatching {
visaErrorAdapter.fromJson(responseError.errorBody!!)?.error?.code ?: responseError.code.numericCode
}.map {
Either.Left(VisaApiError.fromBackendError(it))
}.getOrElse {
Either.Left(VisaApiError.UnknownWithoutCode)
}
}
return Either.Left(VisaApiError.UnknownWithoutCode)
}
}
@AssistedFactory
interface Factory : KycRepository.Factory {
override fun create(userWalletId: UserWalletId): DefaultKycRepository
}
}

View file

@ -0,0 +1,18 @@
package com.tangem.data.pay.di
import com.tangem.data.pay.DefaultKycRepository
import com.tangem.domain.pay.repository.KycRepository
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
internal interface TangemPayDataModule {
@Binds
@Singleton
fun bindKycRepositoryFactory(factory: DefaultKycRepository.Factory): KycRepository.Factory
}

View file

@ -10,9 +10,9 @@ import com.tangem.datasource.api.common.config.ApiEnvironment
import com.tangem.datasource.api.common.config.managers.ApiConfigsManager
import com.tangem.datasource.api.common.response.ApiResponseError
import com.tangem.datasource.api.common.response.getOrThrow
import com.tangem.datasource.api.visa.TangemVisaApi
import com.tangem.datasource.api.visa.models.request.*
import com.tangem.datasource.api.visa.models.response.VisaErrorResponseJsonAdapter
import com.tangem.datasource.api.pay.TangemPayApi
import com.tangem.datasource.api.pay.models.request.*
import com.tangem.datasource.api.pay.models.response.VisaErrorResponseJsonAdapter
import com.tangem.datasource.di.NetworkMoshi
import com.tangem.datasource.local.visa.VisaAuthTokenStorage
import com.tangem.domain.visa.error.VisaApiError
@ -29,7 +29,7 @@ import kotlinx.coroutines.withContext
internal class DefaultVisaActivationRepository @AssistedInject constructor(
@Assisted private val visaCardId: VisaCardId,
@NetworkMoshi private val moshi: Moshi,
private val visaApi: TangemVisaApi,
private val visaApi: TangemPayApi,
private val dispatcherProvider: CoroutineDispatcherProvider,
private val visaAuthTokenStorage: VisaAuthTokenStorage,
private val visaAuthRepository: VisaAuthRepository,
@ -162,7 +162,7 @@ internal class DefaultVisaActivationRepository @AssistedInject constructor(
}
override suspend fun getPinCodeRsaEncryptionPublicKey(): String {
val env = apiConfigsManager.getEnvironmentConfig(ApiConfig.ID.TangemVisa).environment
val env = apiConfigsManager.getEnvironmentConfig(ApiConfig.ID.TangemPay).environment
val rsaPublicKey = visaLibLoader.getOrCreateConfig().rsaPublicKey
return when (env) {
ApiEnvironment.DEV,

View file

@ -4,9 +4,9 @@ import arrow.core.Either
import com.squareup.moshi.Moshi
import com.tangem.datasource.api.common.response.ApiResponseError
import com.tangem.datasource.api.common.response.getOrThrow
import com.tangem.datasource.api.visa.TangemVisaApi
import com.tangem.datasource.api.visa.models.request.*
import com.tangem.datasource.api.visa.models.response.VisaErrorResponseJsonAdapter
import com.tangem.datasource.api.pay.TangemPayApi
import com.tangem.datasource.api.pay.models.request.*
import com.tangem.datasource.api.pay.models.response.VisaErrorResponseJsonAdapter
import com.tangem.datasource.di.NetworkMoshi
import com.tangem.domain.visa.error.VisaApiError
import com.tangem.domain.visa.model.VisaAuthChallenge
@ -21,7 +21,7 @@ import javax.inject.Inject
@Suppress("UnusedPrivateMember")
internal class DefaultVisaAuthRepository @Inject constructor(
@NetworkMoshi private val moshi: Moshi,
private val visaAuthApi: TangemVisaApi,
private val visaAuthApi: TangemPayApi,
private val dispatchers: CoroutineDispatcherProvider,
) : VisaAuthRepository {

View file

@ -14,8 +14,8 @@ import com.tangem.data.common.cache.CacheRegistry
import com.tangem.data.common.quote.QuotesFetcher
import com.tangem.data.visa.config.VisaLibLoader
import com.tangem.data.visa.utils.*
import com.tangem.datasource.api.visa.TangemVisaApi
import com.tangem.datasource.api.visa.models.response.VisaTxHistoryResponse
import com.tangem.datasource.api.pay.TangemPayApi
import com.tangem.datasource.api.pay.models.response.VisaTxHistoryResponse
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.domain.visa.model.VisaCurrency
@ -43,7 +43,7 @@ internal class DefaultVisaRepository @Inject constructor(
private val userWalletsStore: UserWalletsStore,
private val dispatchers: CoroutineDispatcherProvider,
private val visaApiRequestMaker: VisaApiRequestMaker,
private val visaApi: TangemVisaApi,
private val visaApi: TangemPayApi,
private val visaCurrencyFactory: VisaCurrencyFactory,
) : VisaRepository {

View file

@ -1,6 +1,6 @@
package com.tangem.data.visa.converter
import com.tangem.datasource.api.visa.models.response.CardActivationRemoteStateResponse
import com.tangem.datasource.api.pay.models.response.CardActivationRemoteStateResponse
import com.tangem.domain.visa.model.VisaActivationOrderInfo
import com.tangem.domain.visa.model.VisaActivationRemoteState
import com.tangem.utils.converter.Converter

View file

@ -5,8 +5,8 @@ import com.tangem.data.visa.model.AccessCodeData
import com.tangem.datasource.api.common.response.ApiResponse
import com.tangem.datasource.api.common.response.ApiResponseError
import com.tangem.datasource.api.common.response.getOrThrow
import com.tangem.datasource.api.visa.TangemVisaApi
import com.tangem.datasource.api.visa.models.request.RefreshTokenByCardWalletRequest
import com.tangem.datasource.api.pay.TangemPayApi
import com.tangem.datasource.api.pay.models.request.RefreshTokenByCardWalletRequest
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.domain.visa.exception.RefreshTokenExpiredException
@ -25,7 +25,7 @@ typealias VisaAuthorizationHeader = String
internal class VisaApiRequestMaker @Inject constructor(
private val userWalletsStore: UserWalletsStore,
private val visaAuthApi: TangemVisaApi,
private val visaAuthApi: TangemPayApi,
private val accessCodeDataConverter: AccessCodeDataConverter,
private val dispatcherProvider: CoroutineDispatcherProvider,
) {

View file

@ -2,7 +2,7 @@ package com.tangem.data.visa.utils
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.externallinkprovider.TxExploreState
import com.tangem.datasource.api.visa.models.response.VisaTxHistoryResponse
import com.tangem.datasource.api.pay.models.response.VisaTxHistoryResponse
import com.tangem.domain.visa.model.VisaTxDetails
internal class VisaTxDetailsFactory {

View file

@ -1,6 +1,6 @@
package com.tangem.data.visa.utils
import com.tangem.datasource.api.visa.models.response.VisaTxHistoryResponse
import com.tangem.datasource.api.pay.models.response.VisaTxHistoryResponse
import com.tangem.domain.visa.model.VisaTxHistoryItem
internal class VisaTxHistoryItemFactory {

View file

@ -3,7 +3,7 @@ package com.tangem.data.visa.utils
import androidx.paging.PagingSource
import androidx.paging.PagingState
import com.tangem.data.common.cache.CacheRegistry
import com.tangem.datasource.api.visa.models.response.VisaTxHistoryResponse
import com.tangem.datasource.api.pay.models.response.VisaTxHistoryResponse
import com.tangem.domain.visa.model.VisaTxHistoryItem
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.utils.coroutines.CoroutineDispatcherProvider