Updated on 2026-08-14
This commit is contained in:
parent
4e69a47c32
commit
c470e8ef27
8 changed files with 429 additions and 98 deletions
|
|
@ -14,44 +14,52 @@ android {
|
|||
|
||||
dependencies {
|
||||
|
||||
/** Project - Domain */
|
||||
// region Project - Data
|
||||
implementation(projects.data.common)
|
||||
implementation(projects.data.networks)
|
||||
// endregion
|
||||
|
||||
// region Project - Domain
|
||||
implementation(projects.domain.core)
|
||||
implementation(projects.domain.demo)
|
||||
implementation(projects.domain.legacy)
|
||||
implementation(projects.domain.models)
|
||||
implementation(projects.domain.staking)
|
||||
implementation(projects.domain.staking.models)
|
||||
implementation(projects.domain.tokens)
|
||||
implementation(projects.domain.tokens.models)
|
||||
implementation(projects.domain.txhistory.models)
|
||||
implementation(projects.domain.wallets.models)
|
||||
implementation(projects.domain.staking.models)
|
||||
implementation(projects.domain.staking)
|
||||
// endregion
|
||||
|
||||
/** Project - Data */
|
||||
// region Project - Utils
|
||||
implementation(projects.core.datasource)
|
||||
implementation(projects.data.common)
|
||||
|
||||
/** Project - Utils */
|
||||
implementation(projects.core.utils)
|
||||
implementation(projects.domain.legacy)
|
||||
implementation(projects.libs.blockchainSdk)
|
||||
// endregion
|
||||
|
||||
/** Tangem SDKs */
|
||||
// region Tangem SDKs
|
||||
implementation(tangemDeps.blockchain)
|
||||
implementation(tangemDeps.card.core)
|
||||
// endregion
|
||||
|
||||
/** AndroidX */
|
||||
// region AndroidX
|
||||
implementation(deps.androidx.datastore)
|
||||
implementation(deps.androidx.paging.runtime)
|
||||
// endregion
|
||||
|
||||
/** DI */
|
||||
// region DI
|
||||
implementation(deps.hilt.core)
|
||||
kapt(deps.hilt.kapt)
|
||||
// endregion
|
||||
|
||||
/** Other */
|
||||
// region Other
|
||||
implementation(deps.jodatime)
|
||||
implementation(deps.kotlin.coroutines)
|
||||
implementation(deps.moshi.kotlin)
|
||||
implementation(deps.jodatime)
|
||||
implementation(deps.timber)
|
||||
implementation(deps.retrofit) // For HttpException
|
||||
implementation(deps.androidx.paging.runtime)
|
||||
implementation(deps.timber)
|
||||
ksp(deps.moshi.kotlin.codegen)
|
||||
kaptForObfuscatingVariants(deps.retrofit.response.type.keeper)
|
||||
// endregion
|
||||
}
|
||||
|
|
@ -7,7 +7,7 @@ import com.tangem.blockchainsdk.utils.fromNetworkId
|
|||
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.tokens.utils.NetworkStatusFactory
|
||||
import com.tangem.data.networks.utils.NetworkStatusFactory
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import com.tangem.datasource.local.network.NetworksStatusesStore
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
|
|
@ -43,7 +43,6 @@ internal class DefaultNetworksRepository(
|
|||
) : NetworksRepository {
|
||||
|
||||
private val responseCurrenciesFactory = ResponseCryptoCurrenciesFactory(excludedBlockchains)
|
||||
private val networkStatusFactory = NetworkStatusFactory()
|
||||
|
||||
override fun getNetworkStatusesUpdates(
|
||||
userWalletId: UserWalletId,
|
||||
|
|
@ -168,10 +167,10 @@ internal class DefaultNetworksRepository(
|
|||
invalidateCacheKeyIfNeeded(userWalletId, network, result)
|
||||
}
|
||||
|
||||
val networkStatus = networkStatusFactory.createNetworkStatus(
|
||||
val networkStatus = NetworkStatusFactory.create(
|
||||
network = network,
|
||||
result = result,
|
||||
currencies = networkCurrencies.toSet(),
|
||||
updatingResult = result,
|
||||
addedCurrencies = networkCurrencies.toSet(),
|
||||
)
|
||||
|
||||
networksStatusesStore.store(userWalletId, networkStatus)
|
||||
|
|
@ -191,10 +190,10 @@ internal class DefaultNetworksRepository(
|
|||
invalidateCacheKeyIfNeeded(userWalletId, network, result)
|
||||
}
|
||||
|
||||
val networkStatus = networkStatusFactory.createNetworkStatus(
|
||||
val networkStatus = NetworkStatusFactory.create(
|
||||
network = network,
|
||||
result = result,
|
||||
currencies = currencies.toSet(),
|
||||
updatingResult = result,
|
||||
addedCurrencies = currencies.toSet(),
|
||||
)
|
||||
|
||||
networksStatusesStore.store(userWalletId, networkStatus)
|
||||
|
|
|
|||
|
|
@ -1,134 +0,0 @@
|
|||
package com.tangem.data.tokens.utils
|
||||
|
||||
import com.tangem.domain.models.StatusSource
|
||||
import com.tangem.domain.tokens.model.*
|
||||
import com.tangem.domain.txhistory.models.TxHistoryItem
|
||||
import com.tangem.domain.walletmanager.model.Address
|
||||
import com.tangem.domain.walletmanager.model.CryptoCurrencyAmount
|
||||
import com.tangem.domain.walletmanager.model.CryptoCurrencyTransaction
|
||||
import com.tangem.domain.walletmanager.model.UpdateWalletManagerResult
|
||||
import timber.log.Timber
|
||||
|
||||
class NetworkStatusFactory {
|
||||
|
||||
fun createNetworkStatus(
|
||||
network: Network,
|
||||
result: UpdateWalletManagerResult,
|
||||
currencies: Set<CryptoCurrency>,
|
||||
): NetworkStatus {
|
||||
return NetworkStatus(
|
||||
network = network,
|
||||
value = when (result) {
|
||||
is UpdateWalletManagerResult.MissedDerivation -> NetworkStatus.MissedDerivation
|
||||
is UpdateWalletManagerResult.Unreachable -> NetworkStatus.Unreachable(
|
||||
address = getNetworkAddressOrNull(result.selectedAddress, result.addresses),
|
||||
)
|
||||
is UpdateWalletManagerResult.NoAccount -> NetworkStatus.NoAccount(
|
||||
address = getNetworkAddress(result.selectedAddress, result.addresses),
|
||||
amountToCreateAccount = result.amountToCreateAccount,
|
||||
errorMessage = result.errorMessage,
|
||||
source = StatusSource.ACTUAL,
|
||||
)
|
||||
is UpdateWalletManagerResult.Verified -> NetworkStatus.Verified(
|
||||
address = getNetworkAddress(result.selectedAddress, result.addresses),
|
||||
amounts = formatAmounts(result.currenciesAmounts, currencies),
|
||||
pendingTransactions = formatTransactions(
|
||||
transactions = result.currentTransactions,
|
||||
currencies = currencies,
|
||||
),
|
||||
source = StatusSource.ACTUAL,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private fun formatAmounts(
|
||||
amounts: Set<CryptoCurrencyAmount>,
|
||||
currencies: Set<CryptoCurrency>,
|
||||
): Map<CryptoCurrency.ID, CryptoCurrencyAmountStatus> {
|
||||
return currencies.associate { currency ->
|
||||
val amount = when (currency) {
|
||||
is CryptoCurrency.Coin -> {
|
||||
amounts.singleOrNull { it is CryptoCurrencyAmount.Coin }
|
||||
}
|
||||
is CryptoCurrency.Token -> {
|
||||
amounts.firstOrNull { amount ->
|
||||
amount is CryptoCurrencyAmount.Token &&
|
||||
currency.id.rawCurrencyId == amount.tokenId &&
|
||||
currency.contractAddress.equals(amount.tokenContractAddress, ignoreCase = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (amount == null) {
|
||||
Timber.w("Unable to find amount for cryptocurrency: $currency")
|
||||
currency.id to CryptoCurrencyAmountStatus.NotFound
|
||||
} else {
|
||||
currency.id to CryptoCurrencyAmountStatus.Loaded(amount.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun formatTransactions(
|
||||
transactions: Set<CryptoCurrencyTransaction>,
|
||||
currencies: Set<CryptoCurrency>,
|
||||
): Map<CryptoCurrency.ID, Set<TxHistoryItem>> {
|
||||
if (transactions.isEmpty()) return emptyMap()
|
||||
|
||||
return currencies
|
||||
.asSequence()
|
||||
.map { currency ->
|
||||
val currencyTransactions = when (currency) {
|
||||
is CryptoCurrency.Coin -> transactions.filterTo(hashSetOf()) { transaction ->
|
||||
transaction is CryptoCurrencyTransaction.Coin
|
||||
}
|
||||
is CryptoCurrency.Token -> transactions.filterTo(hashSetOf()) { transaction ->
|
||||
transaction is CryptoCurrencyTransaction.Token &&
|
||||
transaction.tokenContractAddress.equals(currency.contractAddress, ignoreCase = true)
|
||||
}
|
||||
}
|
||||
|
||||
currency.id to createCurrentTransactions(currencyTransactions)
|
||||
}
|
||||
.toMap()
|
||||
}
|
||||
|
||||
private fun createCurrentTransactions(transactions: Set<CryptoCurrencyTransaction>): Set<TxHistoryItem> {
|
||||
return transactions.mapTo(hashSetOf()) { it.txHistoryItem }
|
||||
}
|
||||
|
||||
private fun getNetworkAddressOrNull(selectedAddress: String?, availableAddresses: Set<Address>?): NetworkAddress? {
|
||||
if (selectedAddress == null || availableAddresses == null) {
|
||||
return null
|
||||
}
|
||||
|
||||
return getNetworkAddress(selectedAddress, availableAddresses)
|
||||
}
|
||||
|
||||
private fun getNetworkAddress(selectedAddress: String, availableAddresses: Set<Address>): NetworkAddress {
|
||||
val defaultAddress = availableAddresses
|
||||
.firstOrNull { it.value == selectedAddress }
|
||||
?.let(::mapToDomainAddress)
|
||||
|
||||
requireNotNull(defaultAddress) { "Selected address must not be null" }
|
||||
|
||||
return if (availableAddresses.size != 1) {
|
||||
NetworkAddress.Selectable(defaultAddress, availableAddresses.mapTo(hashSetOf(), ::mapToDomainAddress))
|
||||
} else {
|
||||
NetworkAddress.Single(defaultAddress)
|
||||
}
|
||||
}
|
||||
|
||||
private fun mapToDomainAddress(address: Address): NetworkAddress.Address {
|
||||
val type = when (address.type) {
|
||||
Address.Type.Primary -> NetworkAddress.Address.Type.Primary
|
||||
Address.Type.Secondary -> NetworkAddress.Address.Type.Secondary
|
||||
}
|
||||
|
||||
if (address.value.isBlank()) {
|
||||
Timber.w("Address value is blank")
|
||||
}
|
||||
|
||||
return NetworkAddress.Address(address.value, type)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue