Updated on 2026-08-14
This commit is contained in:
parent
63f6ae5dfa
commit
761f896656
12 changed files with 17 additions and 97 deletions
|
|
@ -215,8 +215,6 @@ internal class DefaultCurrenciesRepository(
|
|||
override suspend fun getMultiCurrencyWalletCurrency(
|
||||
userWalletId: UserWalletId,
|
||||
id: CryptoCurrency.ID,
|
||||
contractAddress: String?,
|
||||
derivationPath: Network.DerivationPath,
|
||||
): CryptoCurrency = withContext(dispatchers.io) {
|
||||
val userWallet = getUserWallet(userWalletId)
|
||||
ensureIsCorrectUserWallet(userWallet, isMultiCurrencyWalletExpected = true)
|
||||
|
|
@ -227,10 +225,8 @@ internal class DefaultCurrenciesRepository(
|
|||
|
||||
responseCurrenciesFactory.createCurrency(
|
||||
currencyId = id,
|
||||
contractAddress = contractAddress,
|
||||
response = response,
|
||||
scanResponse = userWallet.scanResponse,
|
||||
derivationPath = derivationPath.value,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,10 +4,9 @@ import com.tangem.blockchain.common.Blockchain
|
|||
import com.tangem.blockchain.common.Token
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import com.tangem.domain.common.DerivationStyleProvider
|
||||
import com.tangem.domain.common.TapWorkarounds.isTestCard
|
||||
import com.tangem.domain.common.extensions.fromNetworkId
|
||||
import com.tangem.domain.common.extensions.toCoinId
|
||||
import com.tangem.domain.common.extensions.toNetworkId
|
||||
import com.tangem.domain.common.util.cardTypesResolver
|
||||
import com.tangem.domain.common.util.derivationStyleProvider
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
|
|
@ -18,26 +17,13 @@ internal class ResponseCryptoCurrenciesFactory {
|
|||
|
||||
fun createCurrency(
|
||||
currencyId: CryptoCurrency.ID,
|
||||
contractAddress: String?,
|
||||
response: UserTokensResponse,
|
||||
scanResponse: ScanResponse,
|
||||
derivationPath: String?,
|
||||
): CryptoCurrency {
|
||||
val responseTokenId = currencyId.rawCurrencyId
|
||||
val networkId = Blockchain.fromId(currencyId.rawNetworkId).toNetworkId()
|
||||
|
||||
val token = requireNotNull(
|
||||
value = response.tokens
|
||||
.find {
|
||||
it.id == responseTokenId && it.networkId == networkId && it.derivationPath == derivationPath &&
|
||||
it.contractAddress == contractAddress
|
||||
},
|
||||
lazyMessage = { "Unable find a token with provided TokenID($responseTokenId) and NetworkID($networkId)" },
|
||||
)
|
||||
|
||||
return requireNotNull(createCurrency(token, scanResponse)) {
|
||||
"Unable to create a currency with provided ID: $currencyId"
|
||||
}
|
||||
return response.tokens
|
||||
.asSequence()
|
||||
.mapNotNull { createCurrency(it, scanResponse) }
|
||||
.first { it.id == currencyId }
|
||||
}
|
||||
|
||||
fun createCurrencies(response: UserTokensResponse, scanResponse: ScanResponse): List<CryptoCurrency> {
|
||||
|
|
@ -56,9 +42,8 @@ internal class ResponseCryptoCurrenciesFactory {
|
|||
}
|
||||
|
||||
val cardDerivationStyleProvider = scanResponse.derivationStyleProvider
|
||||
val card = scanResponse.card
|
||||
|
||||
if (card.isTestCard) {
|
||||
if (scanResponse.cardTypesResolver.isTestCard()) {
|
||||
blockchain = blockchain.getTestnetVersion() ?: blockchain
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -57,9 +57,7 @@ internal class UpdateWalletManagerResultFactory {
|
|||
}
|
||||
|
||||
private fun getTokensAmounts(amounts: Set<Amount>): Set<CryptoCurrencyAmount> {
|
||||
val mutableAmounts = hashSetOf<CryptoCurrencyAmount>()
|
||||
|
||||
return amounts.mapNotNullTo(mutableAmounts, ::createCurrencyAmount)
|
||||
return amounts.mapNotNullTo(hashSetOf(), ::createCurrencyAmount)
|
||||
}
|
||||
|
||||
private fun getDemoTokensAmounts(demoAmount: Amount, tokens: Set<Token>): Set<CryptoCurrencyAmount> {
|
||||
|
|
|
|||
|
|
@ -36,20 +36,16 @@ class FetchCurrencyStatusUseCase(
|
|||
*
|
||||
* @param userWalletId The ID of the user's wallet.
|
||||
* @param id The ID of the cryptocurrency.
|
||||
* @param contractAddress The contract address of the crypto currency
|
||||
* @param derivationPath currency derivation path.
|
||||
* @param refresh Indicates whether to force a refresh of the status data.
|
||||
* @return An [Either] representing success (Right) or an error (Left) in fetching the status.
|
||||
*/
|
||||
suspend operator fun invoke(
|
||||
userWalletId: UserWalletId,
|
||||
id: CryptoCurrency.ID,
|
||||
contractAddress: String?,
|
||||
derivationPath: Network.DerivationPath,
|
||||
refresh: Boolean = false,
|
||||
): Either<CurrencyStatusError, Unit> {
|
||||
return either {
|
||||
val currency = getCurrency(userWalletId, id, contractAddress, derivationPath)
|
||||
val currency = getCurrency(userWalletId, id)
|
||||
|
||||
fetchCurrencyStatus(userWalletId, currency, refresh)
|
||||
}
|
||||
|
|
@ -91,17 +87,10 @@ class FetchCurrencyStatusUseCase(
|
|||
private suspend fun Raise<CurrencyStatusError>.getCurrency(
|
||||
userWalletId: UserWalletId,
|
||||
id: CryptoCurrency.ID,
|
||||
contractAddress: String?,
|
||||
derivationPath: Network.DerivationPath,
|
||||
): CryptoCurrency {
|
||||
return catch(
|
||||
block = {
|
||||
currenciesRepository.getMultiCurrencyWalletCurrency(
|
||||
userWalletId = userWalletId,
|
||||
id = id,
|
||||
contractAddress = contractAddress,
|
||||
derivationPath = derivationPath,
|
||||
)
|
||||
currenciesRepository.getMultiCurrencyWalletCurrency(userWalletId, id)
|
||||
},
|
||||
) {
|
||||
raise(CurrencyStatusError.DataError(it))
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import arrow.core.raise.catch
|
|||
import arrow.core.raise.either
|
||||
import com.tangem.domain.tokens.error.CurrencyStatusError
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.Network
|
||||
import com.tangem.domain.tokens.repository.CurrenciesRepository
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
|
||||
|
|
@ -19,17 +18,13 @@ class GetCryptoCurrencyUseCase(
|
|||
*
|
||||
* @param userWalletId The ID of the user's wallet.
|
||||
* @param id The ID of the cryptocurrency.
|
||||
* @param contractAddress The contract address of the crypto currency
|
||||
* @param derivationPath currency derivation path.
|
||||
* @return An [Either] representing success (Right) or an error (Left) in fetching the status.
|
||||
*/
|
||||
suspend operator fun invoke(
|
||||
userWalletId: UserWalletId,
|
||||
id: CryptoCurrency.ID,
|
||||
contractAddress: String?,
|
||||
derivationPath: Network.DerivationPath,
|
||||
): Either<CurrencyStatusError, CryptoCurrency> {
|
||||
return either { getCurrency(userWalletId, id, contractAddress, derivationPath) }
|
||||
return either { getCurrency(userWalletId, id) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -45,17 +40,10 @@ class GetCryptoCurrencyUseCase(
|
|||
private suspend fun Raise<CurrencyStatusError>.getCurrency(
|
||||
userWalletId: UserWalletId,
|
||||
id: CryptoCurrency.ID,
|
||||
contractAddress: String?,
|
||||
derivationPath: Network.DerivationPath,
|
||||
): CryptoCurrency {
|
||||
return catch(
|
||||
block = {
|
||||
currenciesRepository.getMultiCurrencyWalletCurrency(
|
||||
userWalletId,
|
||||
id,
|
||||
contractAddress,
|
||||
derivationPath,
|
||||
)
|
||||
currenciesRepository.getMultiCurrencyWalletCurrency(userWalletId, id)
|
||||
},
|
||||
catch = { raise(CurrencyStatusError.DataError(it)) },
|
||||
)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import com.tangem.domain.tokens.error.CurrencyStatusError
|
|||
import com.tangem.domain.tokens.error.mapper.mapToCurrencyError
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.tokens.model.Network
|
||||
import com.tangem.domain.tokens.operations.CurrenciesStatusesOperations
|
||||
import com.tangem.domain.tokens.repository.CurrenciesRepository
|
||||
import com.tangem.domain.tokens.repository.NetworksRepository
|
||||
|
|
@ -33,16 +32,12 @@ class GetCurrencyStatusUpdatesUseCase(
|
|||
*
|
||||
* @param userWalletId The unique identifier of the user's wallet.
|
||||
* @param currencyId The unique identifier of the cryptocurrency.
|
||||
* @param contractAddress The contract address of the crypto currency
|
||||
* @param derivationPath currency derivation path.
|
||||
* @param isSingleWalletWithTokens Indicates whether the user wallet contains only one token on card (old cards)
|
||||
* @return A [Flow] emitting either a [CurrencyStatusError] or a [CryptoCurrencyStatus], indicating the result of the fetch operation.
|
||||
*/
|
||||
operator fun invoke(
|
||||
userWalletId: UserWalletId,
|
||||
currencyId: CryptoCurrency.ID,
|
||||
contractAddress: String?,
|
||||
derivationPath: Network.DerivationPath,
|
||||
isSingleWalletWithTokens: Boolean,
|
||||
): Flow<Either<CurrencyStatusError, CryptoCurrencyStatus>> {
|
||||
return flow {
|
||||
|
|
@ -50,8 +45,6 @@ class GetCurrencyStatusUpdatesUseCase(
|
|||
getCurrency(
|
||||
userWalletId = userWalletId,
|
||||
currencyId = currencyId,
|
||||
contractAddress = contractAddress,
|
||||
derivationPath = derivationPath,
|
||||
isSingleWalletWithTokens = isSingleWalletWithTokens,
|
||||
),
|
||||
)
|
||||
|
|
@ -61,9 +54,7 @@ class GetCurrencyStatusUpdatesUseCase(
|
|||
private suspend fun getCurrency(
|
||||
userWalletId: UserWalletId,
|
||||
currencyId: CryptoCurrency.ID,
|
||||
derivationPath: Network.DerivationPath,
|
||||
isSingleWalletWithTokens: Boolean,
|
||||
contractAddress: String?,
|
||||
): Flow<Either<CurrencyStatusError, CryptoCurrencyStatus>> {
|
||||
val operations = CurrenciesStatusesOperations(
|
||||
currenciesRepository = currenciesRepository,
|
||||
|
|
@ -75,7 +66,7 @@ class GetCurrencyStatusUpdatesUseCase(
|
|||
val currencyFlow = if (isSingleWalletWithTokens) {
|
||||
operations.getCurrencyStatusSingleWalletWithTokensFlow(currencyId)
|
||||
} else {
|
||||
operations.getCurrencyStatusFlow(currencyId, contractAddress, derivationPath)
|
||||
operations.getCurrencyStatusFlow(currencyId)
|
||||
}
|
||||
return currencyFlow.map { maybeCurrency ->
|
||||
maybeCurrency.mapLeft(CurrenciesStatusesOperations.Error::mapToCurrencyError)
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@ class GetCurrencyWarningsUseCase(
|
|||
networkId = currency.network.id,
|
||||
currencyId = currency.id,
|
||||
derivationPath = derivationPath,
|
||||
contractAddress = (currency as? CryptoCurrency.Token)?.contractAddress,
|
||||
isSingleWalletWithTokens = isSingleWalletWithTokens,
|
||||
),
|
||||
flowOf(walletManagersFacade.getRentInfo(userWalletId, currency.network)),
|
||||
|
|
@ -63,7 +62,6 @@ class GetCurrencyWarningsUseCase(
|
|||
userWalletId: UserWalletId,
|
||||
networkId: Network.ID,
|
||||
currencyId: CryptoCurrency.ID,
|
||||
contractAddress: String?,
|
||||
derivationPath: Network.DerivationPath,
|
||||
isSingleWalletWithTokens: Boolean,
|
||||
): Flow<List<CryptoCurrencyWarning>> {
|
||||
|
|
@ -77,7 +75,7 @@ class GetCurrencyWarningsUseCase(
|
|||
val currencyFlow = if (isSingleWalletWithTokens) {
|
||||
operations.getCurrencyStatusSingleWalletWithTokensFlow(currencyId)
|
||||
} else {
|
||||
operations.getCurrencyStatusFlow(currencyId, contractAddress, derivationPath)
|
||||
operations.getCurrencyStatusFlow(currencyId)
|
||||
}
|
||||
val networkFlow = if (isSingleWalletWithTokens) {
|
||||
operations.getNetworkCoinForSingleWalletWithTokenFlow(networkId)
|
||||
|
|
|
|||
|
|
@ -105,13 +105,9 @@ internal class CurrenciesStatusesOperations(
|
|||
}
|
||||
}
|
||||
|
||||
suspend fun getCurrencyStatusFlow(
|
||||
currencyId: CryptoCurrency.ID,
|
||||
contractAddress: String?,
|
||||
derivationPath: Network.DerivationPath,
|
||||
): Flow<Either<Error, CryptoCurrencyStatus>> {
|
||||
suspend fun getCurrencyStatusFlow(currencyId: CryptoCurrency.ID): Flow<Either<Error, CryptoCurrencyStatus>> {
|
||||
val currency = recover(
|
||||
block = { getMultiCurrencyWalletCurrency(currencyId, contractAddress, derivationPath) },
|
||||
block = { getMultiCurrencyWalletCurrency(currencyId) },
|
||||
recover = { return flowOf(it.left()) },
|
||||
)
|
||||
|
||||
|
|
@ -245,17 +241,11 @@ internal class CurrenciesStatusesOperations(
|
|||
.onEmpty { emit(Error.EmptyCurrencies.left()) }
|
||||
}
|
||||
|
||||
private suspend fun Raise<Error>.getMultiCurrencyWalletCurrency(
|
||||
currencyId: CryptoCurrency.ID,
|
||||
contractAddress: String?,
|
||||
derivationPath: Network.DerivationPath,
|
||||
): CryptoCurrency {
|
||||
private suspend fun Raise<Error>.getMultiCurrencyWalletCurrency(currencyId: CryptoCurrency.ID): CryptoCurrency {
|
||||
return Either.catch {
|
||||
currenciesRepository.getMultiCurrencyWalletCurrency(
|
||||
userWalletId = userWalletId,
|
||||
id = currencyId,
|
||||
contractAddress = contractAddress,
|
||||
derivationPath = derivationPath,
|
||||
)
|
||||
}
|
||||
.mapLeft { Error.DataError(it) }
|
||||
|
|
|
|||
|
|
@ -127,18 +127,11 @@ interface CurrenciesRepository {
|
|||
*
|
||||
* @param userWalletId The unique identifier of the user wallet.
|
||||
* @param id The unique identifier of the cryptocurrency to be retrieved.
|
||||
* @param contractAddress The contract address of the crypto currency
|
||||
* @param derivationPath currency derivation path.
|
||||
* @return The cryptocurrency associated with the user wallet and ID.
|
||||
* @throws com.tangem.domain.core.error.DataError.UserWalletError.WrongUserWallet If single-currency user wallet
|
||||
* ID provided.
|
||||
*/
|
||||
suspend fun getMultiCurrencyWalletCurrency(
|
||||
userWalletId: UserWalletId,
|
||||
id: CryptoCurrency.ID,
|
||||
contractAddress: String?,
|
||||
derivationPath: Network.DerivationPath,
|
||||
): CryptoCurrency
|
||||
suspend fun getMultiCurrencyWalletCurrency(userWalletId: UserWalletId, id: CryptoCurrency.ID): CryptoCurrency
|
||||
|
||||
/**
|
||||
* Get the coin for a specific network.
|
||||
|
|
|
|||
|
|
@ -80,8 +80,6 @@ internal class MockCurrenciesRepository(
|
|||
override suspend fun getMultiCurrencyWalletCurrency(
|
||||
userWalletId: UserWalletId,
|
||||
id: CryptoCurrency.ID,
|
||||
contractAddress: String?,
|
||||
derivationPath: Network.DerivationPath,
|
||||
): CryptoCurrency {
|
||||
val token = token.getOrElse { e -> throw e }
|
||||
|
||||
|
|
|
|||
|
|
@ -80,8 +80,6 @@ internal class SendViewModel @Inject constructor(
|
|||
getCurrencyStatusUpdatesUseCase(
|
||||
userWalletId = userWalletId,
|
||||
currencyId = cryptoCurrency.id,
|
||||
derivationPath = cryptoCurrency.network.derivationPath,
|
||||
contractAddress = (cryptoCurrency as? CryptoCurrency.Token)?.contractAddress,
|
||||
isSingleWalletWithTokens = isSingleWallet,
|
||||
)
|
||||
.flowWithLifecycle(owner.lifecycle)
|
||||
|
|
|
|||
|
|
@ -160,8 +160,6 @@ internal class TokenDetailsViewModel @Inject constructor(
|
|||
getCurrencyStatusUpdatesUseCase(
|
||||
userWalletId = userWalletId,
|
||||
currencyId = cryptoCurrency.id,
|
||||
contractAddress = (cryptoCurrency as? CryptoCurrency.Token)?.contractAddress,
|
||||
derivationPath = cryptoCurrency.network.derivationPath,
|
||||
isSingleWalletWithTokens = wallet.scanResponse.cardTypesResolver.isSingleWalletWithToken(),
|
||||
)
|
||||
.distinctUntilChanged()
|
||||
|
|
@ -456,8 +454,6 @@ internal class TokenDetailsViewModel @Inject constructor(
|
|||
fetchCurrencyStatusUseCase(
|
||||
userWalletId = userWalletId,
|
||||
id = cryptoCurrency.id,
|
||||
contractAddress = (cryptoCurrency as? CryptoCurrency.Token)?.contractAddress,
|
||||
derivationPath = cryptoCurrency.network.derivationPath,
|
||||
refresh = true,
|
||||
)
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue