Updated on 2026-08-14
This commit is contained in:
parent
41648e4ffc
commit
3dc6ff9548
12 changed files with 400 additions and 1 deletions
|
|
@ -0,0 +1,36 @@
|
|||
package com.tangem.data.express
|
||||
|
||||
import com.tangem.data.common.api.safeApiCall
|
||||
import com.tangem.data.express.converter.ExpressProviderConverter
|
||||
import com.tangem.datasource.api.common.response.getOrThrow
|
||||
import com.tangem.datasource.api.express.TangemExpressApi
|
||||
import com.tangem.datasource.exchangeservice.swap.ExpressUtils
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.domain.express.models.ExpressProvider
|
||||
import com.tangem.domain.express.ExpressRepository
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import timber.log.Timber
|
||||
|
||||
internal class DefaultExpressRepository(
|
||||
private val tangemExpressApi: TangemExpressApi,
|
||||
private val appPreferencesStore: AppPreferencesStore,
|
||||
) : ExpressRepository {
|
||||
|
||||
override suspend fun getProviders(userWallet: UserWallet): List<ExpressProvider> {
|
||||
return safeApiCall(
|
||||
call = {
|
||||
tangemExpressApi.getProviders(
|
||||
userWalletId = userWallet.walletId.stringValue,
|
||||
refCode = ExpressUtils.getRefCode(
|
||||
userWallet = userWallet,
|
||||
appPreferencesStore = appPreferencesStore,
|
||||
),
|
||||
).getOrThrow().map(ExpressProviderConverter()::convert)
|
||||
},
|
||||
onError = {
|
||||
Timber.w(it, "Unable to fetch express providers")
|
||||
throw it
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
package com.tangem.data.express.converter
|
||||
|
||||
import com.squareup.moshi.JsonAdapter
|
||||
import com.tangem.datasource.api.express.models.response.ExpressErrorResponse
|
||||
import com.tangem.domain.express.models.ExpressError
|
||||
import com.tangem.utils.converter.Converter
|
||||
import com.tangem.datasource.api.express.models.response.ExpressError as ExpressErrorDTO
|
||||
|
||||
class ExpressErrorConverter(
|
||||
private val jsonAdapter: JsonAdapter<ExpressErrorResponse>,
|
||||
) : Converter<String, ExpressError> {
|
||||
|
||||
@Suppress("MagicNumber", "CyclomaticComplexMethod")
|
||||
override fun convert(value: String): ExpressError {
|
||||
try {
|
||||
val error: ExpressErrorDTO = jsonAdapter.fromJson(value)?.error ?: return ExpressError.UnknownError
|
||||
|
||||
return when (error.code) {
|
||||
2010 -> ExpressError.BadRequest(code = error.code)
|
||||
2020 -> ExpressError.Forbidden(code = error.code)
|
||||
|
||||
2200 -> ExpressError.InternalError(code = error.code)
|
||||
2210 -> ExpressError.ProviderNotFoundError(code = error.code)
|
||||
2220 -> ExpressError.ProviderNotActiveError(code = error.code)
|
||||
2230 -> ExpressError.ProviderNotAvailableError(code = error.code)
|
||||
2231 -> ExpressError.ProviderInternalError(code = error.code)
|
||||
2240 -> ExpressError.ExchangeNotPossibleError(code = error.code)
|
||||
2250 -> error.toTooSmallAmountError()
|
||||
2251 -> error.toTooBigAmountError()
|
||||
2260 -> error.toNotEnoughAllowanceError()
|
||||
2270 -> ExpressError.NotEnoughBalanceError(code = error.code)
|
||||
2280 -> ExpressError.InvalidAddressError(code = error.code)
|
||||
2290 -> error.toInvalidFromDecimalsError()
|
||||
|
||||
2320 -> error.toProviderDifferentAmountError()
|
||||
else -> ExpressError.DataError(error.code, error.description)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
return ExpressError.UnknownError
|
||||
}
|
||||
}
|
||||
|
||||
private fun ExpressErrorDTO.toTooSmallAmountError(): ExpressError {
|
||||
val minAmount = value?.minAmount ?: return ExpressError.DataError(code, description)
|
||||
val decimals = value?.decimals ?: return ExpressError.DataError(code, description)
|
||||
val requiredAmount = minAmount.toBigDecimalOrNull()?.movePointLeft(decimals)
|
||||
?: return ExpressError.DataError(code, description)
|
||||
|
||||
return ExpressError.AmountError.TooSmallError(code = code, amount = requiredAmount)
|
||||
}
|
||||
|
||||
private fun ExpressErrorDTO.toTooBigAmountError(): ExpressError {
|
||||
val maxAmount = value?.maxAmount ?: return ExpressError.DataError(code, description)
|
||||
val decimals = value?.decimals ?: return ExpressError.DataError(code, description)
|
||||
val requiredAmount = maxAmount.toBigDecimalOrNull()?.movePointLeft(decimals)
|
||||
?: return ExpressError.DataError(code, description)
|
||||
|
||||
return ExpressError.AmountError.TooBigError(code = code, amount = requiredAmount)
|
||||
}
|
||||
|
||||
private fun ExpressErrorDTO.toNotEnoughAllowanceError(): ExpressError {
|
||||
val currentAllowance = value?.currentAllowance ?: return ExpressError.DataError(code, description)
|
||||
|
||||
return ExpressError.AmountError.NotEnoughAllowanceError(code = code, amount = currentAllowance)
|
||||
}
|
||||
|
||||
private fun ExpressErrorDTO.toInvalidFromDecimalsError(): ExpressError {
|
||||
val receivedFromDecimals = value?.receivedFromDecimals ?: return ExpressError.DataError(code, description)
|
||||
val expressFromDecimals = value?.expressFromDecimals ?: return ExpressError.DataError(code, description)
|
||||
|
||||
return ExpressError.InvalidFromDecimalsError(
|
||||
code = code,
|
||||
receivedFromDecimals = receivedFromDecimals,
|
||||
expressFromDecimals = expressFromDecimals,
|
||||
)
|
||||
}
|
||||
|
||||
private fun ExpressErrorDTO.toProviderDifferentAmountError(): ExpressError {
|
||||
val decimals = value?.decimals ?: return ExpressError.DataError(code, description)
|
||||
val fromAmount = value?.fromAmount?.toBigDecimalOrNull() ?: return ExpressError.DataError(code, description)
|
||||
val fromAmountProvider = value?.fromAmountProvider?.toBigDecimalOrNull()
|
||||
?: return ExpressError.DataError(code, description)
|
||||
|
||||
return ExpressError.ProviderDifferentAmountError(
|
||||
code = code,
|
||||
decimals = decimals,
|
||||
fromAmount = fromAmount.movePointLeft(decimals),
|
||||
fromProviderAmount = fromAmountProvider.movePointLeft(decimals),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
package com.tangem.data.express.converter
|
||||
|
||||
import com.tangem.datasource.api.express.models.response.ExchangeProvider
|
||||
import com.tangem.datasource.api.express.models.response.ExchangeProviderType
|
||||
import com.tangem.domain.express.models.ExpressProvider
|
||||
import com.tangem.domain.express.models.ExpressProviderType
|
||||
import com.tangem.utils.converter.Converter
|
||||
|
||||
internal class ExpressProviderConverter : Converter<ExchangeProvider, ExpressProvider> {
|
||||
|
||||
override fun convert(value: ExchangeProvider): ExpressProvider {
|
||||
return ExpressProvider(
|
||||
providerId = value.id,
|
||||
rateTypes = emptyList(),
|
||||
name = value.name,
|
||||
type = convertExchangeType(value.type),
|
||||
imageLarge = value.imageLargeUrl,
|
||||
termsOfUse = value.termsOfUse,
|
||||
privacyPolicy = value.privacyPolicy,
|
||||
isRecommended = value.isRecommended,
|
||||
slippage = value.slippage,
|
||||
)
|
||||
}
|
||||
|
||||
private fun convertExchangeType(type: ExchangeProviderType): ExpressProviderType {
|
||||
return when (type) {
|
||||
ExchangeProviderType.DEX -> ExpressProviderType.DEX
|
||||
ExchangeProviderType.CEX -> ExpressProviderType.CEX
|
||||
ExchangeProviderType.DEX_BRIDGE -> ExpressProviderType.DEX_BRIDGE
|
||||
ExchangeProviderType.ONRAMP -> ExpressProviderType.ONRAMP
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
package com.tangem.data.express.di
|
||||
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.tangem.data.express.DefaultExpressRepository
|
||||
import com.tangem.data.express.converter.ExpressErrorConverter
|
||||
import com.tangem.data.express.error.DefaultExpressErrorResolver
|
||||
import com.tangem.datasource.api.express.TangemExpressApi
|
||||
import com.tangem.datasource.api.express.models.response.ExpressErrorResponse
|
||||
import com.tangem.datasource.di.NetworkMoshi
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.domain.express.ExpressErrorResolver
|
||||
import com.tangem.domain.express.ExpressRepository
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
internal object ExpressDataModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideExpressErrorResolver(@NetworkMoshi moshi: Moshi): ExpressErrorResolver {
|
||||
val jsonAdapter = moshi.adapter(ExpressErrorResponse::class.java)
|
||||
return DefaultExpressErrorResolver(
|
||||
ExpressErrorConverter(jsonAdapter),
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideExpressRepository(
|
||||
tangemExpressApi: TangemExpressApi,
|
||||
appPreferencesStore: AppPreferencesStore,
|
||||
): ExpressRepository {
|
||||
return DefaultExpressRepository(
|
||||
tangemExpressApi = tangemExpressApi,
|
||||
appPreferencesStore = appPreferencesStore,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package com.tangem.data.express.error
|
||||
|
||||
import com.tangem.data.express.converter.ExpressErrorConverter
|
||||
import com.tangem.datasource.api.common.response.ApiResponseError
|
||||
import com.tangem.domain.express.ExpressErrorResolver
|
||||
import com.tangem.domain.express.models.ExpressError
|
||||
|
||||
internal class DefaultExpressErrorResolver(
|
||||
private val expressErrorConverter: ExpressErrorConverter,
|
||||
) : ExpressErrorResolver {
|
||||
|
||||
override fun resolve(throwable: Throwable): ExpressError {
|
||||
return when (throwable) {
|
||||
is ApiResponseError.HttpException -> {
|
||||
expressErrorConverter.convert(throwable.errorBody.orEmpty())
|
||||
}
|
||||
else -> ExpressError.UnknownError
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue