Updated on 2026-08-14
This commit is contained in:
commit
c1cc66fea8
162 changed files with 3408 additions and 1585 deletions
|
|
@ -1,27 +1,14 @@
|
|||
package com.tangem.data.networks.single
|
||||
|
||||
import arrow.core.Either
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchainsdk.utils.ExcludedBlockchains
|
||||
import com.tangem.blockchainsdk.utils.fromNetworkId
|
||||
import com.tangem.data.common.currency.ResponseCryptoCurrenciesFactory
|
||||
import com.tangem.data.common.currency.CardCryptoCurrencyFactory
|
||||
import com.tangem.data.networks.store.NetworksStatusesStoreV2
|
||||
import com.tangem.data.tokens.utils.CardCryptoCurrenciesFactory
|
||||
import com.tangem.data.tokens.utils.NetworkStatusFactory
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.datasource.local.preferences.PreferencesKeys
|
||||
import com.tangem.datasource.local.preferences.utils.getObjectSyncOrNull
|
||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||
import com.tangem.domain.common.util.cardTypesResolver
|
||||
import com.tangem.domain.core.utils.catchOn
|
||||
import com.tangem.domain.demo.DemoConfig
|
||||
import com.tangem.domain.networks.single.SingleNetworkStatusFetcher
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.Network
|
||||
import com.tangem.domain.tokens.model.NetworkStatus
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.withContext
|
||||
import timber.log.Timber
|
||||
|
|
@ -30,27 +17,20 @@ import javax.inject.Inject
|
|||
/**
|
||||
* Default implementation of [SingleNetworkStatusFetcher]
|
||||
*
|
||||
* @param excludedBlockchains excluded blockchains
|
||||
* @property walletManagersFacade wallet managers facade
|
||||
* @property networksStatusesStore networks statuses store
|
||||
* @property userWalletsStore user wallets store
|
||||
* @property appPreferencesStore app preferences store
|
||||
* @property dispatchers dispatchers
|
||||
* @property walletManagersFacade wallet managers facade
|
||||
* @property networksStatusesStore networks statuses store
|
||||
* @property cardCryptoCurrencyFactory card crypto currency factory
|
||||
* @property dispatchers dispatchers
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal class DefaultSingleNetworkStatusFetcher @Inject constructor(
|
||||
excludedBlockchains: ExcludedBlockchains,
|
||||
private val walletManagersFacade: WalletManagersFacade,
|
||||
private val networksStatusesStore: NetworksStatusesStoreV2,
|
||||
private val userWalletsStore: UserWalletsStore,
|
||||
private val appPreferencesStore: AppPreferencesStore,
|
||||
private val cardCryptoCurrencyFactory: CardCryptoCurrencyFactory,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
) : SingleNetworkStatusFetcher {
|
||||
|
||||
private val demoConfig = DemoConfig()
|
||||
private val cardCurrenciesFactory = CardCryptoCurrenciesFactory(demoConfig, excludedBlockchains)
|
||||
private val responseCurrenciesFactory = ResponseCryptoCurrenciesFactory(excludedBlockchains)
|
||||
private val networkStatusFactory = NetworkStatusFactory()
|
||||
|
||||
override suspend fun invoke(params: SingleNetworkStatusFetcher.Params) = Either.catchOn(dispatchers.default) {
|
||||
|
|
@ -59,9 +39,10 @@ internal class DefaultSingleNetworkStatusFetcher @Inject constructor(
|
|||
is SingleNetworkStatusFetcher.Params.Simple -> {
|
||||
networksStatusesStore.refresh(userWalletId = params.userWalletId, network = params.network)
|
||||
|
||||
val userWallet = userWalletsStore.getSyncStrict(key = params.userWalletId)
|
||||
|
||||
createCurrencies(userWallet = userWallet, network = params.network)
|
||||
cardCryptoCurrencyFactory.create(
|
||||
userWalletId = params.userWalletId,
|
||||
network = params.network,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -105,36 +86,4 @@ internal class DefaultSingleNetworkStatusFetcher @Inject constructor(
|
|||
Timber.e("Failed to fetch network status for $params: $it")
|
||||
networksStatusesStore.storeError(userWalletId = params.userWalletId, network = params.network)
|
||||
}
|
||||
|
||||
private suspend fun createCurrencies(userWallet: UserWallet, network: Network): List<CryptoCurrency> {
|
||||
val blockchain = Blockchain.fromNetworkId(networkId = network.backendId)
|
||||
|
||||
// multi-currency wallet
|
||||
if (userWallet.isMultiCurrency) return getMultiWalletCurrencies(userWallet = userWallet, network = network)
|
||||
|
||||
// check if the blockchain of single-currency wallet is the same as network
|
||||
val cardBlockchain = userWallet.scanResponse.cardTypesResolver.getBlockchain()
|
||||
if (cardBlockchain != blockchain) return emptyList()
|
||||
|
||||
// single-currency wallet with token (NODL)
|
||||
if (userWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken()) {
|
||||
return cardCurrenciesFactory.createCurrenciesForSingleCurrencyCardWithToken(userWallet.scanResponse)
|
||||
}
|
||||
|
||||
// single-currency wallet
|
||||
return cardCurrenciesFactory.createPrimaryCurrencyForSingleCurrencyCard(userWallet.scanResponse).let(::listOf)
|
||||
}
|
||||
|
||||
private suspend fun getMultiWalletCurrencies(userWallet: UserWallet, network: Network): List<CryptoCurrency> {
|
||||
val response = appPreferencesStore.getObjectSyncOrNull<UserTokensResponse>(
|
||||
key = PreferencesKeys.getUserTokensKey(userWallet.walletId.stringValue),
|
||||
) ?: return emptyList()
|
||||
|
||||
return responseCurrenciesFactory.createCurrencies(
|
||||
tokens = response.tokens.filter {
|
||||
it.networkId == network.backendId && it.derivationPath == network.derivationPath.value
|
||||
},
|
||||
scanResponse = userWallet.scanResponse,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -2,8 +2,8 @@ package com.tangem.data.networks.single
|
|||
|
||||
import com.google.common.truth.Truth
|
||||
import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory
|
||||
import com.tangem.data.common.currency.CardCryptoCurrencyFactory
|
||||
import com.tangem.data.networks.store.NetworksStatusesStoreV2
|
||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||
import com.tangem.domain.networks.single.SingleNetworkStatusFetcher
|
||||
import com.tangem.domain.tokens.model.NetworkStatus
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
|
|
@ -22,35 +22,35 @@ import org.junit.Test
|
|||
*/
|
||||
internal class DefaultSingleNetworkStatusFetcherTest {
|
||||
|
||||
private val walletManagersFacade: WalletManagersFacade = mockk(relaxed = true)
|
||||
private val networksStatusesStore: NetworksStatusesStoreV2 = mockk(relaxed = true)
|
||||
private val userWalletsStore: UserWalletsStore = mockk(relaxed = true)
|
||||
private val walletManagersFacade: WalletManagersFacade = mockk(relaxUnitFun = true)
|
||||
private val networksStatusesStore: NetworksStatusesStoreV2 = mockk(relaxUnitFun = true)
|
||||
private val cardCryptoCurrencyFactory: CardCryptoCurrencyFactory = mockk()
|
||||
|
||||
private val fetcher = DefaultSingleNetworkStatusFetcher(
|
||||
excludedBlockchains = mockk(relaxed = true),
|
||||
walletManagersFacade = walletManagersFacade,
|
||||
networksStatusesStore = networksStatusesStore,
|
||||
userWalletsStore = userWalletsStore,
|
||||
appPreferencesStore = mockk(relaxed = true),
|
||||
cardCryptoCurrencyFactory = cardCryptoCurrencyFactory,
|
||||
dispatchers = TestingCoroutineDispatcherProvider(),
|
||||
)
|
||||
|
||||
@Test
|
||||
fun `fetch network status successfully`() = runTest {
|
||||
val params = SingleNetworkStatusFetcher.Params.Simple(userWalletId = userWalletId, network = network)
|
||||
val params = createParams()
|
||||
|
||||
coEvery { cardCryptoCurrencyFactory.create(params.userWalletId, params.network) } returns listOf(ethereum)
|
||||
|
||||
val result = UpdateWalletManagerResult.MissedDerivation
|
||||
coEvery { walletManagersFacade.update(userWalletId, network, emptySet()) } returns result
|
||||
coEvery { walletManagersFacade.update(params.userWalletId, params.network, emptySet()) } returns result
|
||||
|
||||
val actual = fetcher(params)
|
||||
|
||||
coVerifyOrder {
|
||||
networksStatusesStore.refresh(userWalletId = userWalletId, network = network)
|
||||
userWalletsStore.getSyncStrict(key = userWalletId)
|
||||
walletManagersFacade.update(userWalletId, network, emptySet())
|
||||
networksStatusesStore.refresh(params.userWalletId, params.network)
|
||||
cardCryptoCurrencyFactory.create(params.userWalletId, params.network)
|
||||
walletManagersFacade.update(params.userWalletId, params.network, emptySet())
|
||||
networksStatusesStore.storeSuccess(
|
||||
userWalletId = userWalletId,
|
||||
value = NetworkStatus(network, NetworkStatus.MissedDerivation),
|
||||
userWalletId = params.userWalletId,
|
||||
value = NetworkStatus(params.network, NetworkStatus.MissedDerivation),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -59,17 +59,17 @@ internal class DefaultSingleNetworkStatusFetcherTest {
|
|||
|
||||
@Test
|
||||
fun `fetch network status failure`() = runTest {
|
||||
val params = SingleNetworkStatusFetcher.Params.Simple(userWalletId = userWalletId, network = network)
|
||||
val params = createParams()
|
||||
|
||||
val exception = IllegalStateException()
|
||||
coEvery { userWalletsStore.getSyncStrict(key = userWalletId) } throws exception
|
||||
coEvery { cardCryptoCurrencyFactory.create(params.userWalletId, params.network) } throws exception
|
||||
|
||||
val actual = fetcher(params)
|
||||
|
||||
coVerifyOrder {
|
||||
networksStatusesStore.refresh(userWalletId = userWalletId, network = network)
|
||||
userWalletsStore.getSyncStrict(key = userWalletId)
|
||||
networksStatusesStore.storeError(userWalletId = userWalletId, network = network)
|
||||
networksStatusesStore.refresh(userWalletId = params.userWalletId, network = params.network)
|
||||
cardCryptoCurrencyFactory.create(userWalletId = params.userWalletId, network = params.network)
|
||||
networksStatusesStore.storeError(userWalletId = params.userWalletId, network = params.network)
|
||||
}
|
||||
|
||||
coVerify(inverse = true) {
|
||||
|
|
@ -81,8 +81,15 @@ internal class DefaultSingleNetworkStatusFetcherTest {
|
|||
Truth.assertThat(actual.leftOrNull()).isEqualTo(exception)
|
||||
}
|
||||
|
||||
private fun createParams(): SingleNetworkStatusFetcher.Params {
|
||||
return SingleNetworkStatusFetcher.Params.Simple(
|
||||
userWalletId = UserWalletId("011"),
|
||||
network = ethereum.network,
|
||||
)
|
||||
}
|
||||
|
||||
private companion object {
|
||||
val userWalletId = UserWalletId("011")
|
||||
val network = MockCryptoCurrencyFactory().ethereum.network
|
||||
|
||||
val ethereum = MockCryptoCurrencyFactory().ethereum
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue