Updated on 2026-08-14
This commit is contained in:
parent
321b764887
commit
33f9a0d452
21 changed files with 280 additions and 157 deletions
|
|
@ -119,6 +119,7 @@ dependencies {
|
|||
implementation(projects.domain.card)
|
||||
implementation(projects.domain.demo)
|
||||
implementation(projects.domain.demo.models)
|
||||
implementation(projects.domain.express)
|
||||
implementation(projects.domain.wallets)
|
||||
implementation(projects.domain.wallets.models)
|
||||
implementation(projects.domain.settings)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
package com.tangem.tap.di
|
||||
|
||||
import com.tangem.blockchainsdk.utils.ExcludedBlockchains
|
||||
import com.tangem.datasource.exchangeservice.swap.ExpressServiceLoader
|
||||
import com.tangem.domain.card.ScanCardUseCase
|
||||
import com.tangem.domain.card.repository.CardSdkConfigRepository
|
||||
import com.tangem.domain.exchange.RampStateManager
|
||||
import com.tangem.domain.express.ExpressServiceFetcher
|
||||
import com.tangem.domain.tokens.GetPolkadotCheckHasImmortalUseCase
|
||||
import com.tangem.domain.tokens.GetPolkadotCheckHasResetUseCase
|
||||
import com.tangem.domain.tokens.repository.CurrenciesRepository
|
||||
|
|
@ -46,14 +46,14 @@ internal object ActivityModule {
|
|||
@Singleton
|
||||
fun provideDefaultRampManager(
|
||||
appStateHolder: AppStateHolder,
|
||||
expressServiceLoader: ExpressServiceLoader,
|
||||
expressServiceFetcher: ExpressServiceFetcher,
|
||||
currenciesRepository: CurrenciesRepository,
|
||||
excludedBlockchains: ExcludedBlockchains,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
): RampStateManager {
|
||||
return DefaultRampManager(
|
||||
sellService = Provider { requireNotNull(appStateHolder.sellService) },
|
||||
expressServiceLoader = expressServiceLoader,
|
||||
expressServiceFetcher = expressServiceFetcher,
|
||||
currenciesRepository = currenciesRepository,
|
||||
dispatchers = dispatchers,
|
||||
excludedBlockchains = excludedBlockchains,
|
||||
|
|
|
|||
|
|
@ -6,12 +6,11 @@ import arrow.core.raise.either
|
|||
import arrow.core.raise.ensure
|
||||
import arrow.core.right
|
||||
import com.tangem.blockchainsdk.utils.ExcludedBlockchains
|
||||
import com.tangem.datasource.api.express.models.TangemExpressValues.EMPTY_CONTRACT_ADDRESS_VALUE
|
||||
import com.tangem.datasource.api.express.models.response.Asset
|
||||
import com.tangem.datasource.exchangeservice.swap.ExpressServiceLoader
|
||||
import com.tangem.domain.core.lce.Lce
|
||||
import com.tangem.domain.exchange.ExpressAvailabilityState
|
||||
import com.tangem.domain.exchange.RampStateManager
|
||||
import com.tangem.domain.express.ExpressServiceFetcher
|
||||
import com.tangem.domain.express.models.ExpressAsset
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
|
|
@ -26,10 +25,9 @@ import com.tangem.utils.isNullOrZero
|
|||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
internal class DefaultRampManager(
|
||||
private val sellService: Provider<ExchangeService>,
|
||||
private val expressServiceLoader: ExpressServiceLoader,
|
||||
private val expressServiceFetcher: ExpressServiceFetcher,
|
||||
private val currenciesRepository: CurrenciesRepository,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
excludedBlockchains: ExcludedBlockchains,
|
||||
|
|
@ -107,7 +105,7 @@ internal class DefaultRampManager(
|
|||
}
|
||||
|
||||
override fun getExpressInitializationStatus(userWalletId: UserWalletId): Flow<ExchangeServiceInitializationStatus> {
|
||||
return expressServiceLoader.getInitializationStatus(userWalletId)
|
||||
return expressServiceFetcher.getInitializationStatus(userWalletId)
|
||||
}
|
||||
|
||||
override suspend fun getSendUnavailabilityReason(
|
||||
|
|
@ -147,14 +145,14 @@ internal class DefaultRampManager(
|
|||
userWalletId: UserWalletId,
|
||||
cryptoCurrency: CryptoCurrency,
|
||||
): ExpressAvailabilityState {
|
||||
val asset = expressServiceLoader.getInitializationStatus(userWalletId).firstOrNull()
|
||||
val asset = expressServiceFetcher.getInitializationStatus(userWalletId).firstOrNull()
|
||||
?: return ExpressAvailabilityState.Loading
|
||||
return when (asset) {
|
||||
is Lce.Error -> ExpressAvailabilityState.Error
|
||||
is Lce.Loading -> ExpressAvailabilityState.Loading
|
||||
is Lce.Content -> {
|
||||
val foundAsset = asset.getOrNull()?.find { cryptoCurrency.findAssetPredicate(it) }
|
||||
foundAsset?.exchangeAvailable?.toSwapAvailabilityState()
|
||||
val foundAsset = asset.getOrNull()?.find { cryptoCurrency.findAssetPredicate(assetId = it.id) }
|
||||
foundAsset?.isExchangeAvailable?.toSwapAvailabilityState()
|
||||
?: ExpressAvailabilityState.AssetNotFound
|
||||
}
|
||||
}
|
||||
|
|
@ -164,15 +162,15 @@ internal class DefaultRampManager(
|
|||
userWalletId: UserWalletId,
|
||||
cryptoCurrency: CryptoCurrency,
|
||||
): ExpressAvailabilityState {
|
||||
val asset = expressServiceLoader.getInitializationStatus(userWalletId).firstOrNull()
|
||||
val asset = expressServiceFetcher.getInitializationStatus(userWalletId).firstOrNull()
|
||||
?: return ExpressAvailabilityState.Loading
|
||||
|
||||
return when (asset) {
|
||||
is Lce.Error -> ExpressAvailabilityState.Error
|
||||
is Lce.Loading -> ExpressAvailabilityState.Loading
|
||||
is Lce.Content -> {
|
||||
val foundAsset = asset.getOrNull()?.find { cryptoCurrency.findAssetPredicate(it) }
|
||||
foundAsset?.onrampAvailable?.toOnrampAvailabilityState()
|
||||
val foundAsset = asset.getOrNull()?.find { cryptoCurrency.findAssetPredicate(assetId = it.id) }
|
||||
foundAsset?.isOnrampAvailable?.toOnrampAvailabilityState()
|
||||
?: ExpressAvailabilityState.AssetNotFound
|
||||
}
|
||||
}
|
||||
|
|
@ -207,8 +205,13 @@ internal class DefaultRampManager(
|
|||
}
|
||||
}
|
||||
|
||||
private fun CryptoCurrency.findAssetPredicate(asset: Asset): Boolean {
|
||||
val contractAddress = (this as? CryptoCurrency.Token)?.contractAddress ?: EMPTY_CONTRACT_ADDRESS_VALUE
|
||||
return asset.network == network.backendId && asset.contractAddress.equals(contractAddress, ignoreCase = true)
|
||||
private fun CryptoCurrency.findAssetPredicate(assetId: ExpressAsset.ID): Boolean {
|
||||
val currencyAssedId = ExpressAsset.ID(
|
||||
networkId = this.network.backendId,
|
||||
contractAddress = (this as? CryptoCurrency.Token)?.contractAddress,
|
||||
)
|
||||
|
||||
return assetId.networkId == currencyAssedId.networkId &&
|
||||
assetId.contractAddress.equals(currencyAssedId.contractAddress, ignoreCase = true)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
package com.tangem.datasource.api.express.models
|
||||
|
||||
object TangemExpressValues {
|
||||
const val EMPTY_CONTRACT_ADDRESS_VALUE = "0"
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
package com.tangem.datasource.di.exchangeservice
|
||||
|
||||
import com.tangem.datasource.exchangeservice.swap.DefaultExpressServiceLoader
|
||||
import com.tangem.datasource.exchangeservice.swap.ExpressServiceLoader
|
||||
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 ExchangeServiceLoaderModule {
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
fun bindExpressServiceLoader(defaultExpressServiceLoader: DefaultExpressServiceLoader): ExpressServiceLoader
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
package com.tangem.datasource.exchangeservice.swap
|
||||
|
||||
import com.tangem.datasource.api.express.models.request.LeastTokenInfo
|
||||
import com.tangem.datasource.api.express.models.response.Asset
|
||||
import com.tangem.domain.core.lce.Lce
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
/**
|
||||
* Express service loader
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
interface ExpressServiceLoader {
|
||||
|
||||
/** Update service using [userWallet] and [userTokens] */
|
||||
suspend fun update(userWallet: UserWallet, userTokens: List<LeastTokenInfo>)
|
||||
|
||||
/** Get initialization status by [userWalletId] */
|
||||
fun getInitializationStatus(userWalletId: UserWalletId): Flow<Lce<Throwable, List<Asset>>>
|
||||
}
|
||||
|
|
@ -1,17 +1,23 @@
|
|||
package com.tangem.datasource.exchangeservice.swap
|
||||
package com.tangem.data.express
|
||||
|
||||
import arrow.core.Either
|
||||
import arrow.core.raise.either
|
||||
import com.tangem.data.express.converter.ExpressAssetConverter
|
||||
import com.tangem.datasource.api.common.response.getOrThrow
|
||||
import com.tangem.datasource.api.express.TangemExpressApi
|
||||
import com.tangem.datasource.api.express.models.request.AssetsRequestBody
|
||||
import com.tangem.datasource.api.express.models.request.LeastTokenInfo
|
||||
import com.tangem.datasource.api.express.models.response.Asset
|
||||
import com.tangem.datasource.exchangeservice.swap.ExpressUtils.getRefCode
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.datasource.local.token.ExpressAssetsStore
|
||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||
import com.tangem.domain.core.lce.Lce
|
||||
import com.tangem.domain.core.utils.catchOn
|
||||
import com.tangem.domain.core.utils.lceContent
|
||||
import com.tangem.domain.core.utils.lceError
|
||||
import com.tangem.domain.core.utils.lceLoading
|
||||
import com.tangem.domain.express.ExpressServiceFetcher
|
||||
import com.tangem.domain.express.models.ExpressAsset
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
|
|
@ -19,56 +25,72 @@ import kotlinx.coroutines.flow.Flow
|
|||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.withContext
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
typealias InitializationStatusFlow = MutableStateFlow<Lce<Throwable, List<Asset>>>
|
||||
typealias InitializationStatusFlow = MutableStateFlow<Lce<Throwable, List<ExpressAsset>>>
|
||||
|
||||
/**
|
||||
* Default implementation of [ExpressServiceLoader]
|
||||
* Default implementation of [ExpressServiceFetcher]
|
||||
*
|
||||
* @property tangemExpressApi express api
|
||||
* @property expressAssetsStore local storage
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal class DefaultExpressServiceLoader @Inject constructor(
|
||||
internal class DefaultExpressServiceFetcher @Inject constructor(
|
||||
private val tangemExpressApi: TangemExpressApi,
|
||||
private val expressAssetsStore: ExpressAssetsStore,
|
||||
private val appPreferencesStore: AppPreferencesStore,
|
||||
private val userWalletsStore: UserWalletsStore,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
) : ExpressServiceLoader {
|
||||
) : ExpressServiceFetcher {
|
||||
|
||||
private val initializationStatuses =
|
||||
MutableStateFlow<Map<UserWalletId, InitializationStatusFlow>>(value = emptyMap())
|
||||
|
||||
override suspend fun update(userWallet: UserWallet, userTokens: List<LeastTokenInfo>) {
|
||||
withContext(dispatchers.io) {
|
||||
override suspend fun fetch(userWalletId: UserWalletId, assetIds: Set<ExpressAsset.ID>): Either<Throwable, Unit> =
|
||||
either {
|
||||
val userWallet = arrow.core.raise.catch(
|
||||
block = { userWalletsStore.getSyncStrict(userWalletId) },
|
||||
catch = ::raise,
|
||||
)
|
||||
|
||||
fetch(userWallet = userWallet, assetIds = assetIds).bind()
|
||||
}
|
||||
|
||||
override suspend fun fetch(userWallet: UserWallet, assetIds: Set<ExpressAsset.ID>): Either<Throwable, Unit> {
|
||||
return Either.catchOn(dispatchers.io) {
|
||||
val initializationStatus = getInitializationStatusInternal(userWallet.walletId)
|
||||
|
||||
try {
|
||||
if (userTokens.isNotEmpty()) {
|
||||
if (assetIds.isNotEmpty()) {
|
||||
val tokenList = assetIds.map {
|
||||
LeastTokenInfo(contractAddress = it.contractAddress, network = it.networkId)
|
||||
}
|
||||
|
||||
val response = tangemExpressApi.getAssets(
|
||||
userWalletId = userWallet.walletId.stringValue,
|
||||
refCode = getRefCode(userWallet, appPreferencesStore),
|
||||
body = AssetsRequestBody(tokensList = userTokens),
|
||||
body = AssetsRequestBody(tokensList = tokenList),
|
||||
).getOrThrow()
|
||||
|
||||
expressAssetsStore.store(userWallet.walletId, response)
|
||||
|
||||
initializationStatus.update { response.lceContent() }
|
||||
val expressAssets = ExpressAssetConverter.convertList(response)
|
||||
initializationStatus.update { expressAssets.lceContent() }
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
if (expressAssetsStore.getSyncOrNull(userWallet.walletId) == null) {
|
||||
initializationStatus.update { e.lceError() }
|
||||
}
|
||||
Timber.e(e, "Unable to fetch assets for: ${userWallet.walletId.stringValue}")
|
||||
throw e
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getInitializationStatus(userWalletId: UserWalletId): Flow<Lce<Throwable, List<Asset>>> {
|
||||
override fun getInitializationStatus(userWalletId: UserWalletId): Flow<Lce<Throwable, List<ExpressAsset>>> {
|
||||
return flow { getInitializationStatusInternal(userWalletId).collect { emit(it) } }
|
||||
}
|
||||
|
||||
|
|
@ -77,7 +99,7 @@ internal class DefaultExpressServiceLoader @Inject constructor(
|
|||
val initializationStatus = initializationStatuses.value[userWalletId]
|
||||
if (initializationStatus != null) return initializationStatus
|
||||
|
||||
val cached = expressAssetsStore.getSyncOrNull(userWalletId)
|
||||
val cached = expressAssetsStore.getSyncOrNull(userWalletId)?.let(ExpressAssetConverter::convertList)
|
||||
val default: InitializationStatusFlow = MutableStateFlow(value = cached?.lceContent() ?: lceLoading())
|
||||
|
||||
initializationStatuses.update { statuses ->
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package com.tangem.data.express.converter
|
||||
|
||||
import com.tangem.datasource.api.express.models.response.Asset
|
||||
import com.tangem.domain.express.models.ExpressAsset
|
||||
import com.tangem.utils.converter.Converter
|
||||
|
||||
/**
|
||||
* Converts an [Asset] from the data layer to an [ExpressAsset] in the domain layer.
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal object ExpressAssetConverter : Converter<Asset, ExpressAsset> {
|
||||
|
||||
override fun convert(value: Asset): ExpressAsset {
|
||||
return ExpressAsset(
|
||||
id = ExpressAsset.ID(
|
||||
networkId = value.network,
|
||||
contractAddress = value.contractAddress,
|
||||
),
|
||||
isExchangeAvailable = value.exchangeAvailable,
|
||||
isOnrampAvailable = value.onrampAvailable,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ package com.tangem.data.express.di
|
|||
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.tangem.data.express.DefaultExpressRepository
|
||||
import com.tangem.data.express.DefaultExpressServiceFetcher
|
||||
import com.tangem.data.express.converter.ExpressErrorConverter
|
||||
import com.tangem.data.express.error.DefaultExpressErrorResolver
|
||||
import com.tangem.datasource.api.express.TangemExpressApi
|
||||
|
|
@ -10,6 +11,7 @@ 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 com.tangem.domain.express.ExpressServiceFetcher
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
|
|
@ -43,4 +45,10 @@ internal object ExpressDataModule {
|
|||
dispatchers = dispatchers,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideExpressServiceFetcher(impl: DefaultExpressServiceFetcher): ExpressServiceFetcher {
|
||||
return impl
|
||||
}
|
||||
}
|
||||
|
|
@ -29,6 +29,7 @@ dependencies {
|
|||
implementation(projects.domain.walletManager)
|
||||
implementation(projects.domain.appTheme.models)
|
||||
implementation(projects.domain.models)
|
||||
implementation(projects.domain.express.models)
|
||||
|
||||
// region DI
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import com.tangem.data.onramp.converters.error.OnrampErrorConverter
|
|||
import com.tangem.datasource.api.common.response.ApiResponseError
|
||||
import com.tangem.datasource.api.common.response.getOrThrow
|
||||
import com.tangem.datasource.api.express.TangemExpressApi
|
||||
import com.tangem.datasource.api.express.models.TangemExpressValues
|
||||
import com.tangem.datasource.api.express.models.response.ExchangeProvider
|
||||
import com.tangem.datasource.api.express.models.response.ExchangeProviderType
|
||||
import com.tangem.datasource.api.express.models.response.ExpressErrorResponse
|
||||
|
|
@ -38,6 +37,7 @@ import com.tangem.datasource.local.preferences.PreferencesKeys
|
|||
import com.tangem.datasource.local.preferences.utils.getObject
|
||||
import com.tangem.datasource.local.preferences.utils.getObjectSyncOrNull
|
||||
import com.tangem.datasource.local.preferences.utils.storeObject
|
||||
import com.tangem.domain.express.models.ExpressAsset
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
|
|
@ -560,7 +560,7 @@ internal class DefaultOnrampRepository(
|
|||
}
|
||||
|
||||
private fun CryptoCurrency.getContractAddress(): String = when (this) {
|
||||
is CryptoCurrency.Coin -> TangemExpressValues.EMPTY_CONTRACT_ADDRESS_VALUE
|
||||
is CryptoCurrency.Coin -> ExpressAsset.EMPTY_CONTRACT_ADDRESS_VALUE
|
||||
is CryptoCurrency.Token -> this.contractAddress
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ dependencies {
|
|||
implementation(projects.domain.card)
|
||||
implementation(projects.domain.core)
|
||||
implementation(projects.domain.demo)
|
||||
implementation(projects.domain.express)
|
||||
implementation(projects.domain.legacy)
|
||||
implementation(projects.domain.models)
|
||||
implementation(projects.domain.staking)
|
||||
|
|
|
|||
|
|
@ -7,15 +7,14 @@ import com.tangem.data.common.currency.UserTokensResponseFactory
|
|||
import com.tangem.data.common.currency.UserTokensSaver
|
||||
import com.tangem.data.tokens.utils.CustomTokensMerger
|
||||
import com.tangem.datasource.api.common.response.ApiResponseError
|
||||
import com.tangem.datasource.api.express.models.TangemExpressValues.EMPTY_CONTRACT_ADDRESS_VALUE
|
||||
import com.tangem.datasource.api.express.models.request.LeastTokenInfo
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import com.tangem.datasource.exchangeservice.swap.ExpressServiceLoader
|
||||
import com.tangem.datasource.local.token.UserTokensResponseStore
|
||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||
import com.tangem.domain.core.utils.catchOn
|
||||
import com.tangem.domain.demo.models.DemoConfig
|
||||
import com.tangem.domain.express.ExpressServiceFetcher
|
||||
import com.tangem.domain.express.models.ExpressAsset
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.isMultiCurrency
|
||||
import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesFetcher
|
||||
|
|
@ -32,7 +31,7 @@ import timber.log.Timber
|
|||
* @property userTokensResponseStore store of [UserTokensResponse]
|
||||
* @property userTokensSaver user tokens saver
|
||||
* @property cardCryptoCurrencyFactory factory for creating crypto currencies for specified card
|
||||
* @property expressServiceLoader express service loader
|
||||
* @property expressServiceFetcher express service loader
|
||||
* @property dispatchers dispatchers
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
|
|
@ -46,7 +45,7 @@ internal class DefaultMultiWalletCryptoCurrenciesFetcher(
|
|||
private val userTokensResponseStore: UserTokensResponseStore,
|
||||
private val userTokensSaver: UserTokensSaver,
|
||||
private val cardCryptoCurrencyFactory: CardCryptoCurrencyFactory,
|
||||
private val expressServiceLoader: ExpressServiceLoader,
|
||||
private val expressServiceFetcher: ExpressServiceFetcher,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
) : MultiWalletCryptoCurrenciesFetcher {
|
||||
|
||||
|
|
@ -109,14 +108,14 @@ internal class DefaultMultiWalletCryptoCurrenciesFetcher(
|
|||
}
|
||||
|
||||
private suspend fun fetchExpressAssetsByNetworkIds(userWallet: UserWallet, userTokens: UserTokensResponse) {
|
||||
val tokens = userTokens.tokens.map { token ->
|
||||
LeastTokenInfo(
|
||||
contractAddress = token.contractAddress ?: EMPTY_CONTRACT_ADDRESS_VALUE,
|
||||
network = token.networkId,
|
||||
val tokens = userTokens.tokens.mapTo(hashSetOf()) { token ->
|
||||
ExpressAsset.ID(
|
||||
networkId = token.networkId,
|
||||
contractAddress = token.contractAddress,
|
||||
)
|
||||
}
|
||||
|
||||
expressServiceLoader.update(userWallet = userWallet, userTokens = tokens)
|
||||
expressServiceFetcher.fetch(userWallet = userWallet, assetIds = tokens)
|
||||
}
|
||||
|
||||
private fun createDefaultUserTokensResponse(userWallet: UserWallet): UserTokensResponse {
|
||||
|
|
|
|||
|
|
@ -7,11 +7,11 @@ import com.tangem.data.tokens.AccountListCryptoCurrenciesFetcher
|
|||
import com.tangem.data.tokens.DefaultMultiWalletCryptoCurrenciesFetcher
|
||||
import com.tangem.data.tokens.utils.CustomTokensMerger
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||
import com.tangem.datasource.exchangeservice.swap.ExpressServiceLoader
|
||||
import com.tangem.datasource.local.token.UserTokensResponseStore
|
||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
|
||||
import com.tangem.domain.demo.models.DemoConfig
|
||||
import com.tangem.domain.express.ExpressServiceFetcher
|
||||
import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesFetcher
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import dagger.Module
|
||||
|
|
@ -33,7 +33,7 @@ internal class MultiWalletCryptoCurrenciesFetcherModule {
|
|||
userTokensResponseStore: UserTokensResponseStore,
|
||||
userTokensSaver: UserTokensSaver,
|
||||
cardCryptoCurrencyFactory: CardCryptoCurrencyFactory,
|
||||
expressServiceLoader: ExpressServiceLoader,
|
||||
expressServiceFetcher: ExpressServiceFetcher,
|
||||
walletAccountsFetcher: WalletAccountsFetcher,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
): MultiWalletCryptoCurrenciesFetcher {
|
||||
|
|
@ -56,7 +56,7 @@ internal class MultiWalletCryptoCurrenciesFetcherModule {
|
|||
userTokensResponseStore = userTokensResponseStore,
|
||||
userTokensSaver = userTokensSaver,
|
||||
cardCryptoCurrencyFactory = cardCryptoCurrencyFactory,
|
||||
expressServiceLoader = expressServiceLoader,
|
||||
expressServiceFetcher = expressServiceFetcher,
|
||||
dispatchers = dispatchers,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,22 +5,14 @@ import com.tangem.data.common.cache.CacheRegistry
|
|||
import com.tangem.data.common.currency.CardCryptoCurrencyFactory
|
||||
import com.tangem.data.common.currency.ResponseCryptoCurrenciesFactory
|
||||
import com.tangem.data.common.currency.UserTokensSaver
|
||||
import com.tangem.data.tokens.repository.DefaultCurrenciesRepository
|
||||
import com.tangem.data.tokens.repository.DefaultCurrencyChecksRepository
|
||||
import com.tangem.data.tokens.repository.DefaultPolkadotAccountHealthCheckRepository
|
||||
import com.tangem.data.tokens.repository.DefaultTokenReceiveWarningsViewedRepository
|
||||
import com.tangem.data.tokens.repository.DefaultYieldSupplyWarningsViewedRepository
|
||||
import com.tangem.data.tokens.repository.*
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||
import com.tangem.datasource.exchangeservice.swap.ExpressServiceLoader
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.datasource.local.token.TokenReceiveWarningActionStore
|
||||
import com.tangem.datasource.local.token.UserTokensResponseStore
|
||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||
import com.tangem.domain.tokens.repository.CurrenciesRepository
|
||||
import com.tangem.domain.tokens.repository.CurrencyChecksRepository
|
||||
import com.tangem.domain.tokens.repository.PolkadotAccountHealthCheckRepository
|
||||
import com.tangem.domain.tokens.repository.TokenReceiveWarningsViewedRepository
|
||||
import com.tangem.domain.tokens.repository.YieldSupplyWarningsViewedRepository
|
||||
import com.tangem.domain.express.ExpressServiceFetcher
|
||||
import com.tangem.domain.tokens.repository.*
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import dagger.Module
|
||||
|
|
@ -42,7 +34,7 @@ internal object TokensDataModule {
|
|||
walletManagersFacade: WalletManagersFacade,
|
||||
cacheRegistry: CacheRegistry,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
expressServiceLoader: ExpressServiceLoader,
|
||||
expressServiceFetcher: ExpressServiceFetcher,
|
||||
excludedBlockchains: ExcludedBlockchains,
|
||||
cardCryptoCurrencyFactory: CardCryptoCurrencyFactory,
|
||||
tokensSaver: UserTokensSaver,
|
||||
|
|
@ -54,7 +46,7 @@ internal object TokensDataModule {
|
|||
walletManagersFacade = walletManagersFacade,
|
||||
cacheRegistry = cacheRegistry,
|
||||
userTokensResponseStore = userTokensResponseStore,
|
||||
expressServiceLoader = expressServiceLoader,
|
||||
expressServiceFetcher = expressServiceFetcher,
|
||||
dispatchers = dispatchers,
|
||||
excludedBlockchains = excludedBlockchains,
|
||||
cardCryptoCurrencyFactory = cardCryptoCurrencyFactory,
|
||||
|
|
|
|||
|
|
@ -10,17 +10,16 @@ import com.tangem.data.common.currency.*
|
|||
import com.tangem.data.tokens.utils.CustomTokensMerger
|
||||
import com.tangem.datasource.api.common.response.ApiResponseError
|
||||
import com.tangem.datasource.api.common.response.getOrThrow
|
||||
import com.tangem.datasource.api.express.models.TangemExpressValues.EMPTY_CONTRACT_ADDRESS_VALUE
|
||||
import com.tangem.datasource.api.express.models.request.LeastTokenInfo
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import com.tangem.datasource.exchangeservice.swap.ExpressServiceLoader
|
||||
import com.tangem.datasource.local.token.UserTokensResponseStore
|
||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||
import com.tangem.domain.card.CardTypesResolver
|
||||
import com.tangem.domain.card.common.util.cardTypesResolver
|
||||
import com.tangem.domain.core.error.DataError
|
||||
import com.tangem.domain.demo.models.DemoConfig
|
||||
import com.tangem.domain.express.ExpressServiceFetcher
|
||||
import com.tangem.domain.express.models.ExpressAsset
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.network.Network
|
||||
|
|
@ -40,7 +39,7 @@ internal class DefaultCurrenciesRepository(
|
|||
private val userWalletsStore: UserWalletsStore,
|
||||
private val walletManagersFacade: WalletManagersFacade,
|
||||
private val cacheRegistry: CacheRegistry,
|
||||
private val expressServiceLoader: ExpressServiceLoader,
|
||||
private val expressServiceFetcher: ExpressServiceFetcher,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
private val cardCryptoCurrencyFactory: CardCryptoCurrencyFactory,
|
||||
private val userTokensSaver: UserTokensSaver,
|
||||
|
|
@ -649,15 +648,15 @@ internal class DefaultCurrenciesRepository(
|
|||
|
||||
// TODO [REDACTED_JIRA]
|
||||
private suspend fun fetchExpressAssetsByNetworkIds(userWallet: UserWallet, userTokens: UserTokensResponse) {
|
||||
val tokens = userTokens.tokens.map { token ->
|
||||
LeastTokenInfo(
|
||||
contractAddress = token.contractAddress ?: EMPTY_CONTRACT_ADDRESS_VALUE,
|
||||
network = token.networkId,
|
||||
val tokens = userTokens.tokens.mapTo(hashSetOf()) { token ->
|
||||
ExpressAsset.ID(
|
||||
networkId = token.networkId,
|
||||
contractAddress = token.contractAddress,
|
||||
)
|
||||
}
|
||||
|
||||
coroutineScope {
|
||||
launch { expressServiceLoader.update(userWallet, tokens) }
|
||||
launch { expressServiceFetcher.fetch(userWallet, tokens) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -666,11 +665,11 @@ internal class DefaultCurrenciesRepository(
|
|||
cryptoCurrencies: List<CryptoCurrency>,
|
||||
refresh: Boolean = false,
|
||||
) {
|
||||
val tokens = cryptoCurrencies.map { currency ->
|
||||
val tokens = cryptoCurrencies.mapTo(hashSetOf()) { currency ->
|
||||
val tokenCurrency = currency as? CryptoCurrency.Token
|
||||
LeastTokenInfo(
|
||||
contractAddress = tokenCurrency?.contractAddress ?: EMPTY_CONTRACT_ADDRESS_VALUE,
|
||||
network = currency.network.backendId,
|
||||
ExpressAsset.ID(
|
||||
networkId = currency.network.backendId,
|
||||
contractAddress = tokenCurrency?.contractAddress,
|
||||
)
|
||||
}
|
||||
cacheRegistry.invokeOnExpire(
|
||||
|
|
@ -678,7 +677,7 @@ internal class DefaultCurrenciesRepository(
|
|||
skipCache = refresh,
|
||||
block = {
|
||||
coroutineScope {
|
||||
launch { expressServiceLoader.update(userWallet, tokens) }
|
||||
launch { expressServiceFetcher.fetch(userWallet, tokens) }
|
||||
}
|
||||
},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -11,14 +11,13 @@ import com.tangem.data.common.currency.UserTokensSaver
|
|||
import com.tangem.data.tokens.utils.CustomTokensMerger
|
||||
import com.tangem.datasource.api.common.response.ApiResponse
|
||||
import com.tangem.datasource.api.common.response.ApiResponseError
|
||||
import com.tangem.datasource.api.express.models.TangemExpressValues.EMPTY_CONTRACT_ADDRESS_VALUE
|
||||
import com.tangem.datasource.api.express.models.request.LeastTokenInfo
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import com.tangem.datasource.exchangeservice.swap.ExpressServiceLoader
|
||||
import com.tangem.datasource.local.token.UserTokensResponseStore
|
||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||
import com.tangem.domain.demo.models.DemoConfig
|
||||
import com.tangem.domain.express.ExpressServiceFetcher
|
||||
import com.tangem.domain.express.models.ExpressAsset
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.models.wallet.isMultiCurrency
|
||||
|
|
@ -45,7 +44,7 @@ internal class DefaultMultiWalletCryptoCurrenciesFetcherTest {
|
|||
private val userTokensResponseStore: UserTokensResponseStore = mockk(relaxUnitFun = true)
|
||||
private val userTokensSaver: UserTokensSaver = mockk(relaxUnitFun = true)
|
||||
private val cardCryptoCurrencyFactory: CardCryptoCurrencyFactory = mockk()
|
||||
private val expressServiceLoader: ExpressServiceLoader = mockk(relaxUnitFun = true)
|
||||
private val expressServiceFetcher: ExpressServiceFetcher = mockk(relaxUnitFun = true)
|
||||
|
||||
private val fetcher = DefaultMultiWalletCryptoCurrenciesFetcher(
|
||||
demoConfig = DemoConfig(),
|
||||
|
|
@ -55,7 +54,7 @@ internal class DefaultMultiWalletCryptoCurrenciesFetcherTest {
|
|||
userTokensResponseStore = userTokensResponseStore,
|
||||
userTokensSaver = userTokensSaver,
|
||||
cardCryptoCurrencyFactory = cardCryptoCurrencyFactory,
|
||||
expressServiceLoader = expressServiceLoader,
|
||||
expressServiceFetcher = expressServiceFetcher,
|
||||
dispatchers = TestingCoroutineDispatcherProvider(),
|
||||
)
|
||||
|
||||
|
|
@ -67,7 +66,7 @@ internal class DefaultMultiWalletCryptoCurrenciesFetcherTest {
|
|||
userTokensResponseStore,
|
||||
userTokensSaver,
|
||||
cardCryptoCurrencyFactory,
|
||||
expressServiceLoader,
|
||||
expressServiceFetcher,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -131,6 +130,13 @@ internal class DefaultMultiWalletCryptoCurrenciesFetcherTest {
|
|||
customTokensMerger.mergeIfPresented(userWalletId = params.userWalletId, response = userTokensResponse)
|
||||
} returns userTokensResponse
|
||||
|
||||
coEvery {
|
||||
expressServiceFetcher.fetch(
|
||||
userWallet = mockUserWallet,
|
||||
assetIds = userTokensResponse.toAssetId(),
|
||||
)
|
||||
} returns Unit.right()
|
||||
|
||||
// Act
|
||||
val actual = fetcher(params)
|
||||
|
||||
|
|
@ -144,7 +150,7 @@ internal class DefaultMultiWalletCryptoCurrenciesFetcherTest {
|
|||
cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyWallet(mockUserWallet)
|
||||
customTokensMerger.mergeIfPresented(userWalletId = params.userWalletId, response = userTokensResponse)
|
||||
userTokensSaver.store(userWalletId = params.userWalletId, response = userTokensResponse)
|
||||
expressServiceLoader.update(userWallet = mockUserWallet, userTokens = userTokensResponse.toLeastTokens())
|
||||
expressServiceFetcher.fetch(userWallet = mockUserWallet, assetIds = userTokensResponse.toAssetId())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -170,6 +176,13 @@ internal class DefaultMultiWalletCryptoCurrenciesFetcherTest {
|
|||
customTokensMerger.mergeIfPresented(userWalletId = params.userWalletId, response = apiResponse.data)
|
||||
} returns apiResponse.data
|
||||
|
||||
coEvery {
|
||||
expressServiceFetcher.fetch(
|
||||
userWallet = mockUserWallet,
|
||||
assetIds = defaultResponse.toAssetId(),
|
||||
)
|
||||
} returns Unit.right()
|
||||
|
||||
// Act
|
||||
val actual = fetcher(params)
|
||||
|
||||
|
|
@ -183,7 +196,7 @@ internal class DefaultMultiWalletCryptoCurrenciesFetcherTest {
|
|||
tangemTechApi.getUserTokens(userId = params.userWalletId.stringValue)
|
||||
customTokensMerger.mergeIfPresented(userWalletId = params.userWalletId, response = apiResponse.data)
|
||||
userTokensSaver.store(userWalletId = params.userWalletId, response = apiResponse.data)
|
||||
expressServiceLoader.update(userWallet = mockUserWallet, userTokens = defaultResponse.toLeastTokens())
|
||||
expressServiceFetcher.fetch(userWallet = mockUserWallet, assetIds = defaultResponse.toAssetId())
|
||||
}
|
||||
|
||||
coVerify(inverse = true) {
|
||||
|
|
@ -212,6 +225,13 @@ internal class DefaultMultiWalletCryptoCurrenciesFetcherTest {
|
|||
customTokensMerger.mergeIfPresented(userWalletId = params.userWalletId, response = apiResponse.data)
|
||||
} returns apiResponse.data
|
||||
|
||||
coEvery {
|
||||
expressServiceFetcher.fetch(
|
||||
userWallet = mockUserWallet,
|
||||
assetIds = apiResponse.data.toAssetId(),
|
||||
)
|
||||
} returns Unit.right()
|
||||
|
||||
// Act
|
||||
val actual = fetcher(params)
|
||||
|
||||
|
|
@ -224,7 +244,7 @@ internal class DefaultMultiWalletCryptoCurrenciesFetcherTest {
|
|||
tangemTechApi.getUserTokens(userId = params.userWalletId.stringValue)
|
||||
customTokensMerger.mergeIfPresented(userWalletId = params.userWalletId, response = apiResponse.data)
|
||||
userTokensSaver.store(userWalletId = params.userWalletId, response = apiResponse.data)
|
||||
expressServiceLoader.update(userWallet = mockUserWallet, userTokens = defaultResponse.toLeastTokens())
|
||||
expressServiceFetcher.fetch(userWallet = mockUserWallet, assetIds = defaultResponse.toAssetId())
|
||||
}
|
||||
|
||||
coVerify(inverse = true) {
|
||||
|
|
@ -273,6 +293,13 @@ internal class DefaultMultiWalletCryptoCurrenciesFetcherTest {
|
|||
customTokensMerger.mergeIfPresented(userWalletId = params.userWalletId, response = userTokensResponse)
|
||||
} returns userTokensResponse
|
||||
|
||||
coEvery {
|
||||
expressServiceFetcher.fetch(
|
||||
userWallet = mockUserWallet,
|
||||
assetIds = userTokensResponse.toAssetId(),
|
||||
)
|
||||
} returns Unit.right()
|
||||
|
||||
// Act
|
||||
val actual = fetcher(params)
|
||||
|
||||
|
|
@ -286,7 +313,7 @@ internal class DefaultMultiWalletCryptoCurrenciesFetcherTest {
|
|||
userTokensResponseStore.getSyncOrNull(userWalletId = userWalletId)
|
||||
customTokensMerger.mergeIfPresented(userWalletId = params.userWalletId, response = userTokensResponse)
|
||||
userTokensSaver.store(userWalletId = params.userWalletId, response = userTokensResponse)
|
||||
expressServiceLoader.update(userWallet = mockUserWallet, userTokens = userTokensResponse.toLeastTokens())
|
||||
expressServiceFetcher.fetch(userWallet = mockUserWallet, assetIds = userTokensResponse.toAssetId())
|
||||
}
|
||||
|
||||
coVerify(inverse = true) {
|
||||
|
|
@ -317,6 +344,13 @@ internal class DefaultMultiWalletCryptoCurrenciesFetcherTest {
|
|||
customTokensMerger.mergeIfPresented(userWalletId = params.userWalletId, response = defaultResponse)
|
||||
} returns defaultResponse
|
||||
|
||||
coEvery {
|
||||
expressServiceFetcher.fetch(
|
||||
userWallet = mockUserWallet,
|
||||
assetIds = defaultResponse.toAssetId(),
|
||||
)
|
||||
} returns Unit.right()
|
||||
|
||||
// Act
|
||||
val actual = fetcher(params)
|
||||
|
||||
|
|
@ -330,7 +364,7 @@ internal class DefaultMultiWalletCryptoCurrenciesFetcherTest {
|
|||
userTokensResponseStore.getSyncOrNull(userWalletId = userWalletId)
|
||||
customTokensMerger.mergeIfPresented(userWalletId = params.userWalletId, response = defaultResponse)
|
||||
userTokensSaver.store(userWalletId = params.userWalletId, response = defaultResponse)
|
||||
expressServiceLoader.update(userWallet = mockUserWallet, userTokens = defaultResponse.toLeastTokens())
|
||||
expressServiceFetcher.fetch(userWallet = mockUserWallet, assetIds = defaultResponse.toAssetId())
|
||||
}
|
||||
|
||||
coVerify(inverse = true) {
|
||||
|
|
@ -383,6 +417,13 @@ internal class DefaultMultiWalletCryptoCurrenciesFetcherTest {
|
|||
customTokensMerger.mergeIfPresented(userWalletId = params.userWalletId, response = userTokensResponse)
|
||||
} returns userTokensResponse
|
||||
|
||||
coEvery {
|
||||
expressServiceFetcher.fetch(
|
||||
userWallet = mockUserWallet,
|
||||
assetIds = userTokensResponse.toAssetId(),
|
||||
)
|
||||
} returns Unit.right()
|
||||
|
||||
// Act
|
||||
val actual = fetcher(params)
|
||||
|
||||
|
|
@ -398,7 +439,7 @@ internal class DefaultMultiWalletCryptoCurrenciesFetcherTest {
|
|||
userTokensSaver.push(userWalletId = params.userWalletId, response = userTokensResponse)
|
||||
customTokensMerger.mergeIfPresented(userWalletId = params.userWalletId, response = userTokensResponse)
|
||||
userTokensSaver.store(userWalletId = params.userWalletId, response = userTokensResponse)
|
||||
expressServiceLoader.update(userWallet = mockUserWallet, userTokens = userTokensResponse.toLeastTokens())
|
||||
expressServiceFetcher.fetch(userWallet = mockUserWallet, assetIds = userTokensResponse.toAssetId())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -429,6 +470,13 @@ internal class DefaultMultiWalletCryptoCurrenciesFetcherTest {
|
|||
customTokensMerger.mergeIfPresented(userWalletId = params.userWalletId, response = defaultResponse)
|
||||
} returns defaultResponse
|
||||
|
||||
coEvery {
|
||||
expressServiceFetcher.fetch(
|
||||
userWallet = mockUserWallet,
|
||||
assetIds = defaultResponse.toAssetId(),
|
||||
)
|
||||
} returns Unit.right()
|
||||
|
||||
// Act
|
||||
val actual = fetcher(params)
|
||||
|
||||
|
|
@ -443,7 +491,7 @@ internal class DefaultMultiWalletCryptoCurrenciesFetcherTest {
|
|||
userTokensSaver.push(userWalletId = params.userWalletId, response = defaultResponse)
|
||||
customTokensMerger.mergeIfPresented(userWalletId = params.userWalletId, response = defaultResponse)
|
||||
userTokensSaver.store(userWalletId = params.userWalletId, response = defaultResponse)
|
||||
expressServiceLoader.update(userWallet = mockUserWallet, userTokens = defaultResponse.toLeastTokens())
|
||||
expressServiceFetcher.fetch(userWallet = mockUserWallet, assetIds = defaultResponse.toAssetId())
|
||||
}
|
||||
|
||||
coVerify(inverse = true) {
|
||||
|
|
@ -471,11 +519,11 @@ internal class DefaultMultiWalletCryptoCurrenciesFetcherTest {
|
|||
),
|
||||
)
|
||||
|
||||
fun UserTokensResponse.toLeastTokens(): List<LeastTokenInfo> {
|
||||
return tokens.map { token ->
|
||||
LeastTokenInfo(
|
||||
contractAddress = token.contractAddress ?: EMPTY_CONTRACT_ADDRESS_VALUE,
|
||||
network = token.networkId,
|
||||
fun UserTokensResponse.toAssetId(): Set<ExpressAsset.ID> {
|
||||
return tokens.mapTo(hashSetOf()) { token ->
|
||||
ExpressAsset.ID(
|
||||
networkId = token.networkId,
|
||||
contractAddress = token.contractAddress,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,24 +1,10 @@
|
|||
plugins {
|
||||
alias(deps.plugins.android.library)
|
||||
alias(deps.plugins.kotlin.android)
|
||||
alias(deps.plugins.kotlin.jvm)
|
||||
alias(deps.plugins.kotlin.serialization)
|
||||
id("configuration")
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "com.tangem.domain.express.models"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
/** Core */
|
||||
implementation(projects.core.utils)
|
||||
implementation(projects.core.datasource)
|
||||
|
||||
/** Domain */
|
||||
implementation(projects.domain.express.models)
|
||||
api(projects.domain.express.models)
|
||||
api(projects.domain.models)
|
||||
implementation(projects.domain.tokens.models)
|
||||
|
||||
/** Other */
|
||||
implementation(deps.moshi.adapters)
|
||||
}
|
||||
|
|
@ -1,12 +1,10 @@
|
|||
plugins {
|
||||
alias(deps.plugins.kotlin.jvm)
|
||||
alias(deps.plugins.kotlin.serialization)
|
||||
id("configuration")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
/** Domain */
|
||||
implementation(projects.domain.tokens.models)
|
||||
|
||||
/* Other */
|
||||
implementation(deps.moshi.adapters)
|
||||
implementation(deps.kotlin.serialization)
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
package com.tangem.domain.express.models
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* Express asset model.
|
||||
*
|
||||
* @property id The unique identifier of the Express asset.
|
||||
* @property isExchangeAvailable Indicates if exchange is available for this asset.
|
||||
* @property isOnrampAvailable Indicates if onramp is available for this asset (nullable).
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@Serializable
|
||||
data class ExpressAsset(
|
||||
val id: ID,
|
||||
val isExchangeAvailable: Boolean,
|
||||
val isOnrampAvailable: Boolean?,
|
||||
) {
|
||||
|
||||
/**
|
||||
* Unique identifier for an Express asset, consisting of network ID and contract address.
|
||||
*
|
||||
* @property networkId The network ID of the asset.
|
||||
* @property contractAddress The contract address of the asset.
|
||||
*/
|
||||
@Serializable
|
||||
data class ID(val networkId: String, val contractAddress: String) {
|
||||
|
||||
companion object {
|
||||
|
||||
/**
|
||||
* Creates an [ID] instance, defaulting the contract address to "0" if null.
|
||||
*
|
||||
* @param networkId The network ID of the asset.
|
||||
* @param contractAddress The contract address of the asset, or null to default to "0".
|
||||
* @return An [ID] instance with the specified network ID and contract address.
|
||||
*/
|
||||
operator fun invoke(networkId: String, contractAddress: String?): ID {
|
||||
return ID(networkId = networkId, contractAddress = contractAddress ?: EMPTY_CONTRACT_ADDRESS_VALUE)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val EMPTY_CONTRACT_ADDRESS_VALUE = "0"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package com.tangem.domain.express
|
||||
|
||||
import arrow.core.Either
|
||||
import com.tangem.domain.core.lce.Lce
|
||||
import com.tangem.domain.express.models.ExpressAsset
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
/**
|
||||
* Service interface to fetch Express assets data and monitor initialization status.
|
||||
*/
|
||||
interface ExpressServiceFetcher {
|
||||
|
||||
/**
|
||||
* Fetches Express assets data for the given user wallet ID and asset IDs.
|
||||
*
|
||||
* @param userWalletId The ID of the user wallet.
|
||||
* @param assetIds The list of Express asset IDs to fetch.
|
||||
*/
|
||||
suspend fun fetch(userWalletId: UserWalletId, assetIds: Set<ExpressAsset.ID>): Either<Throwable, Unit>
|
||||
|
||||
/**
|
||||
* Fetches Express assets data for the given user wallet and asset IDs.
|
||||
*
|
||||
* @param userWallet The user wallet for which to fetch assets.
|
||||
* @param assetIds The list of Express asset IDs to fetch.
|
||||
*/
|
||||
suspend fun fetch(userWallet: UserWallet, assetIds: Set<ExpressAsset.ID>): Either<Throwable, Unit>
|
||||
|
||||
/**
|
||||
* Returns a flow that emits the initialization status of Express assets for the given user wallet ID.
|
||||
*
|
||||
* @param userWalletId The ID of the user wallet.
|
||||
* @return A flow emitting Lce states containing either a list of Express assets or an error.
|
||||
*/
|
||||
fun getInitializationStatus(userWalletId: UserWalletId): Flow<Lce<Throwable, List<ExpressAsset>>>
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue