Updated on 2026-08-14

This commit is contained in:
Tangem 2026-03-12 17:55:33 +03:00
parent bc8bb4da19
commit 07f94d3a95
86 changed files with 317 additions and 387 deletions

View file

@ -26,14 +26,13 @@ import com.tangem.datasource.utils.setTypes
import com.tangem.domain.account.repository.AccountsCRUDRepository
import com.tangem.domain.account.repository.AccountsExpandedRepository
import com.tangem.domain.account.tokens.MainAccountTokensMigration
import com.tangem.utils.coroutines.AppCoroutineScope
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
import javax.inject.Singleton
@Module
@ -69,7 +68,7 @@ internal object AccountDataModule {
fun provideAccountsExpandedRepository(
@NetworkMoshi moshi: Moshi,
@ApplicationContext context: Context,
dispatchers: CoroutineDispatcherProvider,
appScope: AppCoroutineScope,
): AccountsExpandedRepository {
val store = DataStoreFactory.create<Map<String, Set<AccountsExpandedDTO>>>(
serializer = MoshiDataStoreSerializer(
@ -78,7 +77,7 @@ internal object AccountDataModule {
defaultValue = emptyMap(),
),
produceFile = { context.dataStoreFile(fileName = "account_expanded_store") },
scope = CoroutineScope(context = dispatchers.io + SupervisorJob()),
scope = appScope,
)
return DefaultAccountsExpandedRepository(
@ -107,14 +106,14 @@ internal object AccountDataModule {
userTokensSaver: UserTokensSaver,
accountTokenMigrationStore: AccountTokenMigrationStore,
eTagsStore: ETagsStore,
dispatchers: CoroutineDispatcherProvider,
appScope: AppCoroutineScope,
): DefaultMainAccountTokensMigration {
return DefaultMainAccountTokensMigration(
accountsResponseStoreFactory = accountsResponseStoreFactory,
accountTokenMigrationStore = accountTokenMigrationStore,
userTokensSaver = userTokensSaver,
eTagsStore = eTagsStore,
dispatchers = dispatchers,
coroutineScope = appScope,
)
}
}

View file

@ -10,11 +10,9 @@ import com.squareup.moshi.adapter
import com.tangem.datasource.api.tangemTech.models.account.GetWalletAccountsResponse
import com.tangem.datasource.di.NetworkMoshi
import com.tangem.datasource.utils.MoshiDataStoreSerializer
import com.tangem.utils.coroutines.AppCoroutineScope
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
import java.util.concurrent.ConcurrentHashMap
import javax.inject.Inject
import javax.inject.Singleton
@ -35,7 +33,7 @@ typealias AccountsResponseStore = DataStore<GetWalletAccountsResponse?>
internal class AccountsResponseStoreFactory @Inject constructor(
@ApplicationContext private val context: Context,
@NetworkMoshi private val moshi: Moshi,
private val dispatchers: CoroutineDispatcherProvider,
private val appScope: AppCoroutineScope,
) {
@OptIn(ExperimentalStdlibApi::class)
@ -53,7 +51,7 @@ internal class AccountsResponseStoreFactory @Inject constructor(
DataStoreFactory.create(
serializer = MoshiDataStoreSerializer(defaultValue = null, adapter = adapter),
produceFile = { context.dataStoreFile(fileName = "wallet_accounts_${userWalletId.stringValue}") },
scope = CoroutineScope(context = dispatchers.io + SupervisorJob()),
scope = appScope,
)
}
}

View file

@ -20,12 +20,10 @@ import com.tangem.datasource.api.tangemTech.models.account.toUserTokensResponse
import com.tangem.datasource.local.accounts.AccountTokenMigrationStore
import com.tangem.datasource.utils.getSyncOrNull
import com.tangem.domain.account.tokens.MainAccountTokensMigration
import com.tangem.utils.coroutines.AppCoroutineScope
import com.tangem.domain.models.account.DerivationIndex
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.lib.crypto.derivation.AccountNodeRecognizer
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch
import timber.log.Timber
@ -43,11 +41,9 @@ internal class DefaultMainAccountTokensMigration(
private val accountTokenMigrationStore: AccountTokenMigrationStore,
private val userTokensSaver: UserTokensSaver,
private val eTagsStore: ETagsStore,
dispatchers: CoroutineDispatcherProvider,
private val coroutineScope: AppCoroutineScope,
) : MainAccountTokensMigration {
private val coroutineScope = CoroutineScope(dispatchers.default + SupervisorJob())
internal suspend fun migrate(userWalletId: UserWalletId): Either<Throwable, GetWalletAccountsResponse> = either {
val store = accountsResponseStoreFactory.create(userWalletId)
val response = store.getSyncOrNull()

View file

@ -3,8 +3,8 @@ package com.tangem.data.account.store
import android.content.Context
import com.google.common.truth.Truth
import com.squareup.moshi.Moshi
import com.tangem.common.test.TestAppCoroutineScope
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
import io.mockk.clearMocks
import io.mockk.mockk
import org.junit.jupiter.api.AfterEach
@ -19,7 +19,7 @@ class AccountsResponseStoreFactoryTest {
private val factory: AccountsResponseStoreFactory = AccountsResponseStoreFactory(
context = context,
moshi = moshi,
dispatchers = TestingCoroutineDispatcherProvider(),
appScope = TestAppCoroutineScope(),
)
@AfterEach

View file

@ -1,6 +1,7 @@
package com.tangem.data.account.token
import arrow.core.right
import com.tangem.common.test.TestAppCoroutineScope
import com.tangem.data.account.converter.createGetWalletAccountsResponse
import com.tangem.data.account.converter.createWalletAccountDTO
import com.tangem.data.account.store.AccountsResponseStore
@ -18,7 +19,6 @@ import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.test.core.assertEither
import com.tangem.test.core.assertEitherLeft
import com.tangem.test.core.assertEitherRight
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
import io.mockk.*
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.runTest
@ -43,7 +43,7 @@ class DefaultMainAccountTokensMigrationTest {
accountTokenMigrationStore = accountTokenMigrationStore,
userTokensSaver = userTokensSaver,
eTagsStore = eTagsStore,
dispatchers = TestingCoroutineDispatcherProvider(),
coroutineScope = TestAppCoroutineScope(),
)
private val userWalletId = UserWalletId("011")

View file

@ -13,6 +13,7 @@ import com.tangem.datasource.api.tangemTech.TangemTechApi
import com.tangem.datasource.local.appsflyer.AppsFlyerStore
import com.tangem.datasource.local.preferences.AppPreferencesStore
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.utils.coroutines.AppCoroutineScope
import com.tangem.domain.demo.models.DemoConfig
import com.tangem.domain.walletmanager.WalletManagersFacade
import com.tangem.domain.wallets.repository.WalletsRepository
@ -22,8 +23,6 @@ import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
import javax.inject.Singleton
@Module
@ -69,6 +68,7 @@ internal object DataCommonModule {
dispatchers: CoroutineDispatcherProvider,
addressesEnricher: UserTokensResponseAddressesEnricher,
walletServerBinder: WalletServerBinder,
appScope: AppCoroutineScope,
): UserTokensSaver {
return UserTokensSaver(
tangemTechApi = tangemTechApi,
@ -76,7 +76,7 @@ internal object DataCommonModule {
dispatchers = dispatchers,
addressesEnricher = addressesEnricher,
pushTokensRetryerPool = RetryerPool(
coroutineScope = CoroutineScope(SupervisorJob() + dispatchers.default),
coroutineScope = appScope,
),
walletServerBinder = walletServerBinder,
)

View file

@ -151,7 +151,7 @@ internal class DefaultQuotesFetcherTest {
quotes = setOf(
QuoteMetadata(
cryptoCurrencyId = "ethereum",
timestamp = DateTime.now().millis - 10_000,
timestamp = DateTime.now().millis - 20_000,
value = cachedQuote,
),
),
@ -194,7 +194,7 @@ internal class DefaultQuotesFetcherTest {
quotes = setOf(
QuoteMetadata(
cryptoCurrencyId = "ethereum",
timestamp = DateTime.now().millis - 10_000,
timestamp = DateTime.now().millis - 20_000,
value = cachedQuote,
),
QuoteMetadata(
@ -385,7 +385,7 @@ internal class DefaultQuotesFetcherTest {
quotes = setOf(
QuoteMetadata(
cryptoCurrencyId = "solana",
timestamp = DateTime.now().millis - 10_000,
timestamp = DateTime.now().millis - 20_000,
value = MockQuoteResponseFactory.createSinglePrice(BigDecimal.ZERO),
),
),

View file

@ -15,6 +15,7 @@ import com.tangem.datasource.local.network.entity.NetworkStatusDM
import com.tangem.datasource.utils.MoshiDataStoreSerializer
import com.tangem.datasource.utils.mapWithStringKeyTypes
import com.tangem.datasource.utils.setTypes
import com.tangem.utils.coroutines.AppCoroutineScope
import com.tangem.domain.networks.repository.NetworksRepository
import com.tangem.domain.networks.utils.NetworksCleaner
import com.tangem.domain.walletmanager.WalletManagersFacade
@ -24,8 +25,6 @@ import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
import javax.inject.Singleton
@Module
@ -37,7 +36,7 @@ internal object NetworkDataModule {
fun provideNetworksStatusesStore(
@NetworkMoshi moshi: Moshi,
@ApplicationContext context: Context,
dispatchers: CoroutineDispatcherProvider,
appScope: AppCoroutineScope,
): NetworksStatusesStore {
return DefaultNetworksStatusesStore(
context = context,
@ -49,9 +48,9 @@ internal object NetworkDataModule {
defaultValue = emptyMap(),
),
produceFile = { context.dataStoreFile(fileName = "networks_statuses_2") },
scope = CoroutineScope(context = dispatchers.io + SupervisorJob()),
scope = appScope,
),
dispatchers = dispatchers,
scope = appScope,
)
}

View file

@ -7,11 +7,11 @@ import com.tangem.data.networks.converters.SimpleNetworkStatusConverter
import com.tangem.data.networks.models.SimpleNetworkStatus
import com.tangem.datasource.local.datastore.RuntimeSharedStore
import com.tangem.datasource.local.network.entity.NetworkStatusDM
import com.tangem.utils.coroutines.AppCoroutineScope
import com.tangem.domain.models.StatusSource
import com.tangem.domain.models.network.Network
import com.tangem.domain.models.network.NetworkStatus
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.extensions.addOrReplace
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
@ -33,11 +33,9 @@ internal class DefaultNetworksStatusesStore(
context: Context,
private val runtimeStore: RuntimeSharedStore<WalletIdWithSimpleStatus>,
private val persistenceDataStore: DataStore<WalletIdWithStatusDM>,
dispatchers: CoroutineDispatcherProvider,
private val scope: AppCoroutineScope,
) : NetworksStatusesStore {
private val scope = CoroutineScope(context = SupervisorJob() + dispatchers.io)
init {
scope.launch {
try {

View file

@ -2,6 +2,7 @@ package com.tangem.data.networks.store
import com.google.common.truth.Truth
import com.tangem.blockchain.common.Blockchain
import com.tangem.common.test.TestAppCoroutineScope
import com.tangem.common.test.datastore.MockStateDataStore
import com.tangem.common.test.domain.network.MockNetworkStatusFactory
import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory
@ -10,7 +11,6 @@ import com.tangem.data.networks.toSimple
import com.tangem.datasource.local.datastore.RuntimeSharedStore
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.test.core.getEmittedValues
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
import io.mockk.mockk
import kotlinx.coroutines.test.runTest
import org.junit.Test
@ -27,7 +27,7 @@ internal class GetTest {
context = mockk(),
runtimeStore = runtimeStore,
persistenceDataStore = persistenceStore,
dispatchers = TestingCoroutineDispatcherProvider(),
scope = TestAppCoroutineScope(),
)
@Test

View file

@ -2,6 +2,7 @@ package com.tangem.data.networks.store
import androidx.datastore.core.DataStore
import com.google.common.truth.Truth
import com.tangem.common.test.TestAppCoroutineScope
import com.tangem.common.test.datastore.MockStateDataStore
import com.tangem.common.test.domain.network.MockNetworkStatusFactory
import com.tangem.data.networks.models.SimpleNetworkStatus
@ -10,7 +11,6 @@ import com.tangem.data.networks.toSimple
import com.tangem.datasource.local.datastore.RuntimeSharedStore
import com.tangem.domain.models.StatusSource
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
import io.mockk.every
import io.mockk.mockk
import kotlinx.coroutines.flow.emptyFlow
@ -33,7 +33,7 @@ internal class InitializationTest {
context = mockk(),
runtimeStore = runtimeStore,
persistenceDataStore = persistenceStore,
dispatchers = TestingCoroutineDispatcherProvider(),
scope = TestAppCoroutineScope(),
)
Truth.assertThat(runtimeStore.getSyncOrNull()).isEqualTo(null)
@ -48,7 +48,7 @@ internal class InitializationTest {
context = mockk(),
runtimeStore = runtimeStore,
persistenceDataStore = persistenceStore,
dispatchers = TestingCoroutineDispatcherProvider(),
scope = TestAppCoroutineScope(),
)
Truth.assertThat(runtimeStore.getSyncOrNull()).isEqualTo(emptyMap<String, Set<SimpleNetworkStatus>>())
@ -71,7 +71,7 @@ internal class InitializationTest {
context = mockk(),
runtimeStore = runtimeStore,
persistenceDataStore = persistenceStore,
dispatchers = TestingCoroutineDispatcherProvider(),
scope = TestAppCoroutineScope(),
)
val expectedStatus = status.toSimple().copy(value = status.value.copySealed(source = StatusSource.CACHE))

View file

@ -1,6 +1,7 @@
package com.tangem.data.networks.store
import com.google.common.truth.Truth
import com.tangem.common.test.TestAppCoroutineScope
import com.tangem.common.test.datastore.MockStateDataStore
import com.tangem.common.test.domain.network.MockNetworkStatusFactory
import com.tangem.data.networks.models.SimpleNetworkStatus
@ -10,7 +11,6 @@ import com.tangem.datasource.local.datastore.RuntimeSharedStore
import com.tangem.domain.models.StatusSource
import com.tangem.domain.models.network.NetworkStatus
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
import io.mockk.mockk
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.test.runTest
@ -31,7 +31,7 @@ internal class ParameterizedStoreStatusTest(private val model: Model) {
context = mockk(),
runtimeStore = runtimeStore,
persistenceDataStore = persistenceStore,
dispatchers = TestingCoroutineDispatcherProvider(),
scope = TestAppCoroutineScope(),
)
@Test

View file

@ -1,6 +1,7 @@
package com.tangem.data.networks.store
import com.google.common.truth.Truth
import com.tangem.common.test.TestAppCoroutineScope
import com.tangem.common.test.datastore.MockStateDataStore
import com.tangem.common.test.domain.network.MockNetworkStatusFactory
import com.tangem.data.networks.models.SimpleNetworkStatus
@ -10,7 +11,6 @@ import com.tangem.datasource.local.datastore.RuntimeSharedStore
import com.tangem.domain.models.StatusSource
import com.tangem.domain.models.network.NetworkStatus
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
import io.mockk.mockk
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.test.runTest
@ -31,7 +31,7 @@ internal class ParameterizedStoreSuccessTest(private val model: Model) {
context = mockk(),
runtimeStore = runtimeStore,
persistenceDataStore = persistenceStore,
dispatchers = TestingCoroutineDispatcherProvider(),
scope = TestAppCoroutineScope(),
)
@Test

View file

@ -1,6 +1,7 @@
package com.tangem.data.networks.store
import com.google.common.truth.Truth
import com.tangem.common.test.TestAppCoroutineScope
import com.tangem.common.test.datastore.MockStateDataStore
import com.tangem.common.test.domain.network.MockNetworkStatusFactory
import com.tangem.data.networks.models.SimpleNetworkStatus
@ -9,7 +10,6 @@ import com.tangem.data.networks.toSimple
import com.tangem.datasource.local.datastore.RuntimeSharedStore
import com.tangem.domain.models.network.NetworkStatus
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
import io.mockk.mockk
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.test.runTest
@ -30,7 +30,7 @@ internal class ParameterizedStoreTest(private val model: Model) {
context = mockk(),
runtimeStore = runtimeStore,
persistenceDataStore = persistenceStore,
dispatchers = TestingCoroutineDispatcherProvider(),
scope = TestAppCoroutineScope(),
)
@Test

View file

@ -1,6 +1,7 @@
package com.tangem.data.networks.store
import com.google.common.truth.Truth
import com.tangem.common.test.TestAppCoroutineScope
import com.tangem.common.test.datastore.MockStateDataStore
import com.tangem.common.test.domain.network.MockNetworkStatusFactory
import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory
@ -10,7 +11,6 @@ import com.tangem.datasource.local.network.entity.NetworkStatusDM
import com.tangem.domain.models.StatusSource
import com.tangem.domain.models.network.NetworkStatus
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
import io.mockk.mockk
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.test.runTest
@ -28,7 +28,7 @@ internal class SetSourceAsCacheTest {
context = mockk(),
runtimeStore = runtimeStore,
persistenceDataStore = persistenceStore,
dispatchers = TestingCoroutineDispatcherProvider(),
scope = TestAppCoroutineScope(),
)
@Test

View file

@ -1,6 +1,7 @@
package com.tangem.data.networks.store
import com.google.common.truth.Truth
import com.tangem.common.test.TestAppCoroutineScope
import com.tangem.common.test.datastore.MockStateDataStore
import com.tangem.common.test.domain.network.MockNetworkStatusFactory
import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory
@ -10,7 +11,6 @@ import com.tangem.datasource.local.network.entity.NetworkStatusDM
import com.tangem.domain.models.StatusSource
import com.tangem.domain.models.network.NetworkStatus
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
import io.mockk.mockk
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.test.runTest
@ -28,7 +28,7 @@ internal class SetSourceAsOnlyCacheTest {
context = mockk(),
runtimeStore = runtimeStore,
persistenceDataStore = persistenceStore,
dispatchers = TestingCoroutineDispatcherProvider(),
scope = TestAppCoroutineScope(),
)
@Test

View file

@ -1,6 +1,7 @@
package com.tangem.data.networks.store
import com.google.common.truth.Truth
import com.tangem.common.test.TestAppCoroutineScope
import com.tangem.common.test.datastore.MockStateDataStore
import com.tangem.common.test.domain.network.MockNetworkStatusFactory
import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory
@ -10,7 +11,6 @@ import com.tangem.datasource.local.datastore.RuntimeSharedStore
import com.tangem.datasource.local.network.entity.NetworkStatusDM
import com.tangem.domain.models.StatusSource
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
import io.mockk.mockk
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.test.runTest
@ -28,7 +28,7 @@ internal class StoreStatusTest {
context = mockk(),
runtimeStore = runtimeStore,
persistenceDataStore = persistenceStore,
dispatchers = TestingCoroutineDispatcherProvider(),
scope = TestAppCoroutineScope(),
)
@Test

View file

@ -1,6 +1,7 @@
package com.tangem.data.networks.store
import com.google.common.truth.Truth
import com.tangem.common.test.TestAppCoroutineScope
import com.tangem.common.test.datastore.MockStateDataStore
import com.tangem.common.test.domain.network.MockNetworkStatusFactory
import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory
@ -9,7 +10,6 @@ import com.tangem.data.networks.toSimple
import com.tangem.datasource.local.datastore.RuntimeSharedStore
import com.tangem.domain.models.StatusSource
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
import io.mockk.mockk
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.test.runTest
@ -27,7 +27,7 @@ internal class StoreSuccessTest {
context = mockk(),
runtimeStore = runtimeStore,
persistenceDataStore = persistenceStore,
dispatchers = TestingCoroutineDispatcherProvider(),
scope = TestAppCoroutineScope(),
)
@Test

View file

@ -1,6 +1,7 @@
package com.tangem.data.networks.store
import com.google.common.truth.Truth
import com.tangem.common.test.TestAppCoroutineScope
import com.tangem.common.test.datastore.MockStateDataStore
import com.tangem.common.test.domain.network.MockNetworkStatusFactory
import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory
@ -9,7 +10,6 @@ import com.tangem.data.networks.toSimple
import com.tangem.datasource.local.datastore.RuntimeSharedStore
import com.tangem.domain.models.StatusSource
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
import io.mockk.mockk
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.test.runTest
@ -27,7 +27,7 @@ internal class StoreTest {
context = mockk(),
runtimeStore = runtimeStore,
persistenceDataStore = persistenceStore,
dispatchers = TestingCoroutineDispatcherProvider(),
scope = TestAppCoroutineScope(),
)
@Test

View file

@ -1,6 +1,7 @@
package com.tangem.data.networks.store
import com.google.common.truth.Truth
import com.tangem.common.test.TestAppCoroutineScope
import com.tangem.common.test.datastore.MockStateDataStore
import com.tangem.common.test.domain.network.MockNetworkStatusFactory
import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory
@ -13,7 +14,6 @@ import com.tangem.domain.models.StatusSource
import com.tangem.domain.models.network.NetworkAddress
import com.tangem.domain.models.network.NetworkStatus
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
import io.mockk.mockk
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.test.runTest
@ -31,7 +31,7 @@ internal class UpdateStatusSourceTest {
context = mockk(),
runtimeStore = runtimeStore,
persistenceDataStore = persistenceStore,
dispatchers = TestingCoroutineDispatcherProvider(),
scope = TestAppCoroutineScope(),
)
@Test

View file

@ -22,6 +22,7 @@ import com.tangem.domain.card.common.extensions.canHandleToken
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.domain.common.wallets.getSyncStrict
import com.tangem.domain.common.wallets.loadAndGet
import com.tangem.utils.coroutines.AppCoroutineScope
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.onramp.model.HotCryptoCurrency
@ -30,10 +31,9 @@ import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.coroutines.JobHolder
import com.tangem.utils.coroutines.runCatching
import com.tangem.utils.coroutines.saveIn
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.plus
import timber.log.Timber
/**
@ -59,9 +59,10 @@ internal class DefaultHotCryptoRepository(
private val walletAccountsFetcher: WalletAccountsFetcher,
private val dispatchers: CoroutineDispatcherProvider,
private val analyticsEventHandler: AnalyticsEventHandler,
appScope: AppCoroutineScope,
) : HotCryptoRepository {
private val coroutineScope = CoroutineScope(dispatchers.main + SupervisorJob())
private val coroutineScope = appScope + dispatchers.main
private val hotCryptoJobHolder = JobHolder()

View file

@ -28,6 +28,7 @@ import com.tangem.datasource.local.onramp.sepa.OnrampCurrentCountryByIPStore
import com.tangem.datasource.local.onramp.sepa.OnrampSepaAvailabilityStore
import com.tangem.datasource.local.preferences.AppPreferencesStore
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.utils.coroutines.AppCoroutineScope
import com.tangem.domain.onramp.repositories.*
import com.tangem.domain.walletmanager.WalletManagersFacade
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
@ -109,6 +110,7 @@ internal object OnrampDataModule {
dispatchers: CoroutineDispatcherProvider,
analyticsEventHandler: AnalyticsEventHandler,
walletAccountsFetcher: WalletAccountsFetcher,
appScope: AppCoroutineScope,
): HotCryptoRepository {
return DefaultHotCryptoRepository(
excludedBlockchains = excludedBlockchains,
@ -119,6 +121,7 @@ internal object OnrampDataModule {
dispatchers = dispatchers,
analyticsEventHandler = analyticsEventHandler,
walletAccountsFetcher = walletAccountsFetcher,
appScope = appScope,
)
}

View file

@ -14,17 +14,15 @@ import com.tangem.datasource.di.NetworkMoshi
import com.tangem.datasource.local.datastore.RuntimeSharedStore
import com.tangem.datasource.utils.MoshiDataStoreSerializer
import com.tangem.datasource.utils.mapWithStringKeyTypes
import com.tangem.utils.coroutines.AppCoroutineScope
import com.tangem.domain.quotes.QuotesRepository
import com.tangem.domain.quotes.multi.MultiQuoteStatusFetcher
import com.tangem.domain.quotes.multi.MultiQuoteUpdater
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
import javax.inject.Singleton
@Module
@ -36,7 +34,7 @@ internal object QuotesDataModule {
fun provideQuotesStoreV2(
@NetworkMoshi moshi: Moshi,
@ApplicationContext context: Context,
dispatchers: CoroutineDispatcherProvider,
appScope: AppCoroutineScope,
): QuotesStatusesStore {
return DefaultQuotesStatusesStore(
runtimeStore = RuntimeSharedStore(),
@ -47,9 +45,9 @@ internal object QuotesDataModule {
defaultValue = emptyMap(),
),
produceFile = { context.dataStoreFile(fileName = "quotes") },
scope = CoroutineScope(context = dispatchers.io + SupervisorJob()),
scope = appScope,
),
dispatchers = dispatchers,
scope = appScope,
)
}
@ -65,13 +63,13 @@ internal object QuotesDataModule {
appCurrencyResponseStore: AppCurrencyResponseStore,
quotesStatusesStore: QuotesStatusesStore,
multiQuoteStatusFetcher: MultiQuoteStatusFetcher,
dispatchers: CoroutineDispatcherProvider,
coroutineScope: AppCoroutineScope,
): MultiQuoteUpdater {
return DefaultMultiQuoteUpdater(
appCurrencyResponseStore = appCurrencyResponseStore,
quotesStatusesStore = quotesStatusesStore,
multiQuoteStatusFetcher = multiQuoteStatusFetcher,
dispatchers = dispatchers,
coroutineScope = coroutineScope,
)
}
}

View file

@ -4,16 +4,14 @@ import androidx.annotation.VisibleForTesting
import arrow.core.left
import com.tangem.data.quotes.store.QuotesStatusesStore
import com.tangem.datasource.appcurrency.AppCurrencyResponseStore
import com.tangem.utils.coroutines.AppCoroutineScope
import com.tangem.domain.core.utils.EitherFlow
import com.tangem.domain.models.quote.QuoteStatus
import com.tangem.domain.quotes.multi.MultiQuoteStatusFetcher
import com.tangem.domain.quotes.multi.MultiQuoteUpdater
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.coroutines.JobHolder
import com.tangem.utils.coroutines.saveIn
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.*
import timber.log.Timber
@ -32,10 +30,9 @@ internal class DefaultMultiQuoteUpdater(
private val appCurrencyResponseStore: AppCurrencyResponseStore,
private val quotesStatusesStore: QuotesStatusesStore,
private val multiQuoteStatusFetcher: MultiQuoteStatusFetcher,
dispatchers: CoroutineDispatcherProvider,
private val coroutineScope: AppCoroutineScope,
) : MultiQuoteUpdater {
private val coroutineScope = CoroutineScope(SupervisorJob() + dispatchers.default)
private val updaterHolder = JobHolder()
override fun subscribe() {

View file

@ -4,13 +4,11 @@ import androidx.datastore.core.DataStore
import com.tangem.data.quotes.converter.QuoteStatusConverter
import com.tangem.datasource.api.tangemTech.models.QuotesResponse
import com.tangem.datasource.local.datastore.RuntimeSharedStore
import com.tangem.utils.coroutines.AppCoroutineScope
import com.tangem.domain.models.StatusSource
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.quote.QuoteStatus
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.extensions.addOrReplace
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.firstOrNull
@ -29,11 +27,9 @@ internal typealias CurrencyIdWithQuote = Map<String, QuotesResponse.Quote>
internal class DefaultQuotesStatusesStore(
private val runtimeStore: RuntimeSharedStore<Set<QuoteStatus>>,
private val persistenceDataStore: DataStore<CurrencyIdWithQuote>,
dispatchers: CoroutineDispatcherProvider,
private val scope: AppCoroutineScope,
) : QuotesStatusesStore {
private val scope = CoroutineScope(context = SupervisorJob() + dispatchers.io)
init {
scope.launch {
val cachedStatuses = persistenceDataStore.data.firstOrNull()

View file

@ -2,12 +2,12 @@ package com.tangem.data.quotes.multi
import arrow.core.right
import com.google.common.truth.Truth
import com.tangem.common.test.TestAppCoroutineScope
import com.tangem.data.quotes.store.QuotesStatusesStore
import com.tangem.datasource.api.tangemTech.models.CurrenciesResponse
import com.tangem.datasource.appcurrency.AppCurrencyResponseStore
import com.tangem.domain.quotes.multi.MultiQuoteStatusFetcher
import com.tangem.test.core.getEmittedValues
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
import io.mockk.*
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.test.runTest
@ -26,7 +26,7 @@ internal class DefaultMultiQuoteStatusUpdaterTest {
appCurrencyResponseStore = appCurrencyResponseStore,
quotesStatusesStore = quotesStore,
multiQuoteStatusFetcher = multiQuoteStatusFetcher,
dispatchers = TestingCoroutineDispatcherProvider(),
coroutineScope = TestAppCoroutineScope(),
)
@Test

View file

@ -1,6 +1,7 @@
package com.tangem.data.quotes.store
import com.google.common.truth.Truth
import com.tangem.common.test.TestAppCoroutineScope
import com.tangem.common.test.data.quote.MockQuoteResponseFactory
import com.tangem.common.test.data.quote.toDomain
import com.tangem.common.test.datastore.MockStateDataStore
@ -9,7 +10,6 @@ import com.tangem.domain.models.StatusSource
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.quote.QuoteStatus
import com.tangem.test.core.ProvideTestModels
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Nested
@ -39,7 +39,7 @@ internal class QuotesStatusesStoreExtTest {
store = DefaultQuotesStatusesStore(
runtimeStore = runtimeStore,
persistenceDataStore = persistenceStore,
dispatchers = TestingCoroutineDispatcherProvider(),
scope = TestAppCoroutineScope(),
)
}

View file

@ -2,6 +2,7 @@ package com.tangem.data.quotes.store
import androidx.datastore.core.DataStore
import com.google.common.truth.Truth
import com.tangem.common.test.TestAppCoroutineScope
import com.tangem.common.test.data.quote.MockQuoteResponseFactory
import com.tangem.common.test.data.quote.toDomain
import com.tangem.common.test.datastore.MockStateDataStore
@ -11,7 +12,6 @@ import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.quote.QuoteStatus
import com.tangem.test.core.ProvideTestModels
import com.tangem.test.core.getEmittedValues
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
import io.mockk.every
import io.mockk.mockk
import kotlinx.coroutines.flow.emptyFlow
@ -53,7 +53,7 @@ internal class QuotesStatusesStoreTest {
store = DefaultQuotesStatusesStore(
runtimeStore = runtimeStore,
persistenceDataStore = persistenceStore,
dispatchers = TestingCoroutineDispatcherProvider(),
scope = TestAppCoroutineScope(),
)
}
@ -73,7 +73,7 @@ internal class QuotesStatusesStoreTest {
DefaultQuotesStatusesStore(
runtimeStore = runtimeStore,
persistenceDataStore = persistenceStore,
dispatchers = TestingCoroutineDispatcherProvider(),
scope = TestAppCoroutineScope(),
)
val actual = runtimeStore.getSyncOrNull()
@ -93,7 +93,7 @@ internal class QuotesStatusesStoreTest {
DefaultQuotesStatusesStore(
runtimeStore = runtimeStore,
persistenceDataStore = persistenceStore,
dispatchers = TestingCoroutineDispatcherProvider(),
scope = TestAppCoroutineScope(),
)
val actual = runtimeStore.getSyncOrNull()
@ -120,7 +120,7 @@ internal class QuotesStatusesStoreTest {
DefaultQuotesStatusesStore(
runtimeStore = runtimeStore,
persistenceDataStore = persistenceStore,
dispatchers = TestingCoroutineDispatcherProvider(),
scope = TestAppCoroutineScope(),
)
val actual = runtimeStore.getSyncOrNull()

View file

@ -8,11 +8,11 @@ import com.tangem.data.staking.store.StakeKitBalancesStore
import com.tangem.datasource.api.ethpool.models.response.P2PEthPoolAccountResponse
import com.tangem.datasource.api.stakekit.models.response.model.YieldBalanceWrapperDTO
import com.tangem.datasource.local.datastore.RuntimeSharedStore
import com.tangem.utils.coroutines.AppCoroutineScope
import com.tangem.domain.staking.multi.MultiStakingBalanceProducer
import com.tangem.domain.staking.multi.MultiStakingBalanceSupplier
import com.tangem.domain.staking.single.SingleStakingBalanceProducer
import com.tangem.domain.staking.single.SingleStakingBalanceSupplier
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
@ -27,12 +27,12 @@ internal object StakingBalanceSupplierModule {
@Singleton
fun provideStakingBalancesStore(
persistenceStore: DataStore<Map<String, Set<YieldBalanceWrapperDTO>>>,
dispatchers: CoroutineDispatcherProvider,
scope: AppCoroutineScope,
): StakeKitBalancesStore {
return DefaultStakeKitBalancesStore(
runtimeStore = RuntimeSharedStore(),
persistenceStore = persistenceStore,
dispatchers = dispatchers,
scope = scope,
)
}
@ -40,12 +40,12 @@ internal object StakingBalanceSupplierModule {
@Singleton
fun provideP2PEthPoolBalancesStore(
persistenceStore: DataStore<Map<String, Set<P2PEthPoolAccountResponse>>>,
dispatchers: CoroutineDispatcherProvider,
scope: AppCoroutineScope,
): P2PEthPoolBalancesStore {
return DefaultP2PEthPoolBalancesStore(
runtimeStore = RuntimeSharedStore(),
persistenceStore = persistenceStore,
dispatchers = dispatchers,
scope = scope,
)
}

View file

@ -4,14 +4,12 @@ import androidx.datastore.core.DataStore
import com.tangem.data.staking.converters.ethpool.P2PEthPoolStakingBalanceConverter
import com.tangem.datasource.api.ethpool.models.response.P2PEthPoolAccountResponse
import com.tangem.datasource.local.datastore.RuntimeSharedStore
import com.tangem.utils.coroutines.AppCoroutineScope
import com.tangem.domain.models.StatusSource
import com.tangem.domain.models.staking.StakingBalance
import com.tangem.domain.models.staking.StakingID
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.extensions.addOrReplace
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.firstOrNull
@ -33,11 +31,9 @@ internal typealias WalletIdWithP2PEthPoolResponses = Map<String, Set<P2PEthPoolA
internal class DefaultP2PEthPoolBalancesStore(
private val runtimeStore: RuntimeSharedStore<WalletIdWithP2PStakingBalances>,
private val persistenceStore: DataStore<WalletIdWithP2PEthPoolResponses>,
dispatchers: CoroutineDispatcherProvider,
private val scope: AppCoroutineScope,
) : P2PEthPoolBalancesStore {
private val scope = CoroutineScope(context = SupervisorJob() + dispatchers.io)
init {
scope.launch {
val cachedData = persistenceStore.data.firstOrNull() ?: return@launch

View file

@ -4,14 +4,12 @@ import androidx.datastore.core.DataStore
import com.tangem.datasource.api.stakekit.models.response.model.YieldBalanceWrapperDTO
import com.tangem.datasource.local.datastore.RuntimeSharedStore
import com.tangem.datasource.local.token.converter.StakingBalanceConverter
import com.tangem.utils.coroutines.AppCoroutineScope
import com.tangem.domain.models.StatusSource
import com.tangem.domain.models.staking.StakingBalance
import com.tangem.domain.models.staking.StakingID
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.extensions.addOrReplace
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.firstOrNull
@ -33,11 +31,9 @@ internal typealias WalletIdWithStakingBalances = Map<UserWalletId, Set<StakingBa
internal class DefaultStakeKitBalancesStore(
private val runtimeStore: RuntimeSharedStore<WalletIdWithStakingBalances>,
private val persistenceStore: DataStore<WalletIdWithWrappers>,
dispatchers: CoroutineDispatcherProvider,
private val scope: AppCoroutineScope,
) : StakeKitBalancesStore {
private val scope = CoroutineScope(context = SupervisorJob() + dispatchers.io)
init {
scope.launch {
val cachedStatuses = persistenceStore.data.firstOrNull() ?: return@launch

View file

@ -1,6 +1,7 @@
package com.tangem.data.staking.store
import com.google.common.truth.Truth
import com.tangem.common.test.TestAppCoroutineScope
import com.tangem.common.test.data.staking.MockYieldBalanceWrapperDTOFactory
import com.tangem.common.test.datastore.MockStateDataStore
import com.tangem.data.staking.toDomain
@ -8,7 +9,6 @@ import com.tangem.datasource.local.datastore.RuntimeSharedStore
import com.tangem.domain.models.staking.StakingBalance
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.test.core.getEmittedValues
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
import kotlinx.coroutines.test.runTest
import org.junit.Test
@ -23,7 +23,7 @@ internal class StakingBalancesStoreGetMethodTest {
private val store = DefaultStakeKitBalancesStore(
runtimeStore = runtimeStore,
persistenceStore = persistenceStore,
dispatchers = TestingCoroutineDispatcherProvider(),
scope = TestAppCoroutineScope(),
)
@Test

View file

@ -2,13 +2,13 @@ package com.tangem.data.staking.store
import androidx.datastore.core.DataStore
import com.google.common.truth.Truth
import com.tangem.common.test.TestAppCoroutineScope
import com.tangem.common.test.data.staking.MockYieldBalanceWrapperDTOFactory
import com.tangem.common.test.datastore.MockStateDataStore
import com.tangem.data.staking.toDomain
import com.tangem.datasource.local.datastore.RuntimeSharedStore
import com.tangem.domain.models.staking.StakingBalance
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
import io.mockk.every
import io.mockk.mockk
import kotlinx.coroutines.flow.emptyFlow
@ -30,7 +30,7 @@ internal class StakingBalancesStoreInitializationTest {
DefaultStakeKitBalancesStore(
runtimeStore = runtimeStore,
persistenceStore = persistenceStore,
dispatchers = TestingCoroutineDispatcherProvider(),
scope = TestAppCoroutineScope(),
)
Truth.assertThat(runtimeStore.getSyncOrNull()).isEqualTo(null)
@ -44,7 +44,7 @@ internal class StakingBalancesStoreInitializationTest {
DefaultStakeKitBalancesStore(
runtimeStore = runtimeStore,
persistenceStore = persistenceStore,
dispatchers = TestingCoroutineDispatcherProvider(),
scope = TestAppCoroutineScope(),
)
Truth.assertThat(runtimeStore.getSyncOrNull()).isEqualTo(emptyMap<String, Set<StakingBalance>>())
@ -66,7 +66,7 @@ internal class StakingBalancesStoreInitializationTest {
DefaultStakeKitBalancesStore(
runtimeStore = runtimeStore,
persistenceStore = persistenceStore,
dispatchers = TestingCoroutineDispatcherProvider(),
scope = TestAppCoroutineScope(),
)
val expected = mapOf(userWalletId to setOf(wrapper.toDomain()))

View file

@ -1,6 +1,7 @@
package com.tangem.data.staking.store
import com.google.common.truth.Truth
import com.tangem.common.test.TestAppCoroutineScope
import com.tangem.common.test.data.staking.MockYieldBalanceWrapperDTOFactory
import com.tangem.common.test.datastore.MockStateDataStore
import com.tangem.data.staking.toDomain
@ -10,7 +11,6 @@ import com.tangem.domain.models.StatusSource
import com.tangem.domain.models.staking.StakingBalance
import com.tangem.domain.models.staking.StakingID
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.test.runTest
import org.junit.Test
@ -26,7 +26,7 @@ internal class StakingBalancesStoreUpdateMethodsTest {
private val store = DefaultStakeKitBalancesStore(
runtimeStore = runtimeStore,
persistenceStore = persistenceStore,
dispatchers = TestingCoroutineDispatcherProvider(),
scope = TestAppCoroutineScope(),
)
@Test

View file

@ -2,6 +2,7 @@ package com.tangem.data.pay
import com.tangem.common.card.FirmwareVersion
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.utils.coroutines.AppCoroutineScope
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.models.wallet.isLocked
@ -9,7 +10,6 @@ import com.tangem.domain.models.wallet.isMultiCurrency
import com.tangem.domain.pay.TangemPayEligibilityManager
import com.tangem.domain.pay.repository.OnboardingRepository
import com.tangem.hot.sdk.model.HotWalletId
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.sync.Mutex
@ -17,15 +17,14 @@ import kotlinx.coroutines.sync.withLock
import javax.inject.Inject
internal class DefaultTangemPayEligibilityManager @Inject constructor(
dispatchers: CoroutineDispatcherProvider,
private val userWalletsListRepository: UserWalletsListRepository,
private val coroutineScope: AppCoroutineScope,
private val onboardingRepository: OnboardingRepository,
) : TangemPayEligibilityManager {
private var cachedEligibleWallets: List<UserWalletData>? = null
private var eligibleWalletsDeferred: Deferred<List<UserWalletData>>? = null
private val loadMutex = Mutex()
private val coroutineScope = CoroutineScope(SupervisorJob() + dispatchers.default)
init {
resetDataWhenWalletsUpdate()

View file

@ -18,6 +18,7 @@ import com.tangem.datasource.local.datastore.RuntimeSharedStore
import com.tangem.datasource.local.visa.entity.PaymentAccountStatusDM
import com.tangem.datasource.utils.MoshiDataStoreSerializer
import com.tangem.datasource.utils.mapWithStringKeyTypes
import com.tangem.utils.coroutines.AppCoroutineScope
import com.tangem.domain.pay.TangemPayCryptoCurrencyFactory
import com.tangem.domain.pay.TangemPayEligibilityManager
import com.tangem.domain.pay.flow.PaymentAccountStatusFetcher
@ -38,8 +39,6 @@ import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
import javax.inject.Singleton
@Module
@ -112,6 +111,7 @@ internal interface TangemPayDataModule {
@NetworkMoshi moshi: Moshi,
@ApplicationContext context: Context,
dispatchers: CoroutineDispatcherProvider,
scope: AppCoroutineScope,
): PaymentAccountStatusesStore {
return PaymentAccountStatusesStore(
runtimeStore = RuntimeSharedStore(),
@ -122,9 +122,9 @@ internal interface TangemPayDataModule {
defaultValue = emptyMap(),
),
produceFile = { context.dataStoreFile(fileName = "payment_account_statuses") },
scope = CoroutineScope(context = dispatchers.io + SupervisorJob()),
scope = scope,
),
dispatchers = dispatchers,
scope = scope,
)
}

View file

@ -19,6 +19,7 @@ import com.tangem.datasource.api.pay.models.response.FreezeUnfreezeCardResponse
import com.tangem.datasource.api.pay.models.response.OrderResponse.Result.Status
import com.tangem.datasource.local.visa.TangemPayCardFrozenStateStore
import com.tangem.datasource.local.visa.TangemPayStorage
import com.tangem.utils.coroutines.AppCoroutineScope
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.pay.model.SetPinResult
import com.tangem.domain.pay.model.TangemPayCardBalance
@ -45,9 +46,9 @@ internal class DefaultTangemPayCardDetailsRepository @Inject constructor(
private val storage: TangemPayStorage,
private val cardFrozenStateStore: TangemPayCardFrozenStateStore,
private val errorConverter: TangemPayErrorConverter,
private val pollingScope: AppCoroutineScope,
) : TangemPayCardDetailsRepository {
private val pollingScope = CoroutineScope(Dispatchers.IO + SupervisorJob())
private val pollingJobs = mutableMapOf<String, Job>()
private val storePollingMutex = Mutex()

View file

@ -9,6 +9,7 @@ import com.tangem.datasource.api.pay.models.request.WithdrawDataRequest
import com.tangem.datasource.api.pay.models.request.WithdrawRequest
import com.tangem.datasource.api.pay.models.response.WithdrawResponse
import com.tangem.datasource.local.visa.TangemPayStorage
import com.tangem.utils.coroutines.AppCoroutineScope
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.pay.TangemPayWithdrawExchangeState
@ -46,9 +47,9 @@ internal class DefaultTangemPayWithdrawRepository @Inject constructor(
private val tangemPayStorage: TangemPayStorage,
private val swapRepository: SwapRepository,
private val orderRepository: CustomerOrderRepository,
private val withdrawPollingScope: AppCoroutineScope,
) : TangemPayWithdrawRepository {
private val withdrawPollingScope = CoroutineScope(Dispatchers.IO + SupervisorJob())
private val withdrawPollingJobs = mutableMapOf<String, Job>()
private val withdrawPollingMutex = Mutex()

View file

@ -4,11 +4,9 @@ import androidx.datastore.core.DataStore
import com.tangem.data.pay.converter.PaymentAccountStatusDMConverter
import com.tangem.datasource.local.datastore.RuntimeSharedStore
import com.tangem.datasource.local.visa.entity.PaymentAccountStatusDM
import com.tangem.utils.coroutines.AppCoroutineScope
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.pay.PaymentAccountStatus
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.firstOrNull
@ -28,11 +26,9 @@ internal typealias WalletIdWithPaymentStatusDM = Map<String, PaymentAccountStatu
internal class PaymentAccountStatusesStore(
private val runtimeStore: RuntimeSharedStore<WalletIdWithPaymentStatus>,
private val persistenceDataStore: DataStore<WalletIdWithPaymentStatusDM>,
dispatchers: CoroutineDispatcherProvider,
private val scope: AppCoroutineScope,
) {
private val scope = CoroutineScope(context = SupervisorJob() + dispatchers.io)
init {
scope.launch {
try {

View file

@ -17,7 +17,6 @@ import com.tangem.data.walletconnect.respond.WcRespondService
import com.tangem.data.walletconnect.sessions.DefaultWcSessionsManager
import com.tangem.data.walletconnect.utils.WcNamespaceConverter
import com.tangem.data.walletconnect.utils.WcNetworksConverter
import com.tangem.data.walletconnect.utils.WcScope
import com.tangem.datasource.di.SdkMoshi
import com.tangem.datasource.local.walletconnect.WalletConnectStore
import com.tangem.domain.account.status.supplier.SingleAccountStatusListSupplier
@ -34,6 +33,7 @@ import com.tangem.domain.walletconnect.usecase.initialize.WcInitializeUseCase
import com.tangem.domain.walletconnect.usecase.pair.WcPairUseCase
import com.tangem.domain.walletmanager.WalletManagersFacade
import com.tangem.domain.wallets.usecase.GetWalletsUseCase
import com.tangem.utils.coroutines.AppCoroutineScope
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import dagger.Module
import dagger.Provides
@ -80,8 +80,8 @@ internal object WalletConnectDataModule {
@Provides
@Singleton
fun sdkDelegate(wcScope: WcScope, store: WalletConnectStore): WcPairSdkDelegate = WcPairSdkDelegate(
scope = wcScope,
fun sdkDelegate(appScope: AppCoroutineScope, store: WalletConnectStore): WcPairSdkDelegate = WcPairSdkDelegate(
scope = appScope,
store = store,
)
@ -93,7 +93,7 @@ internal object WalletConnectDataModule {
getWallets: GetWalletsUseCase,
wcNetworksConverter: WcNetworksConverter,
analytics: AnalyticsEventHandler,
wcScope: WcScope,
appScope: AppCoroutineScope,
): DefaultWcSessionsManager {
return DefaultWcSessionsManager(
store = store,
@ -101,7 +101,7 @@ internal object WalletConnectDataModule {
getWallets = getWallets,
wcNetworksConverter = wcNetworksConverter,
analytics = analytics,
scope = wcScope,
scope = appScope,
)
}
@ -109,10 +109,6 @@ internal object WalletConnectDataModule {
@Singleton
fun wcSessionsManager(default: DefaultWcSessionsManager): WcSessionsManager = default
@Provides
@Singleton
fun wcScope(dispatchers: CoroutineDispatcherProvider): WcScope = WcScope(dispatchers)
@Provides
@Singleton
fun wcRequestService(default: DefaultWcRequestService): WcRequestService = default

View file

@ -6,13 +6,13 @@ import arrow.core.right
import com.reown.walletkit.client.Wallet
import com.reown.walletkit.client.WalletKit
import com.tangem.data.walletconnect.utils.WC_TAG
import com.tangem.data.walletconnect.utils.WcScope
import com.tangem.data.walletconnect.utils.WcSdkObserver
import com.tangem.datasource.local.walletconnect.WalletConnectStore
import com.tangem.data.walletconnect.utils.getDappOriginUrl
import com.tangem.domain.walletconnect.model.WcPairError
import com.tangem.domain.walletconnect.model.WcPairError.ApprovalFailed
import com.tangem.domain.walletconnect.model.WcPendingApprovalSessionDTO
import com.tangem.utils.coroutines.AppCoroutineScope
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.awaitClose
@ -22,7 +22,7 @@ import kotlin.coroutines.resume
import kotlin.time.Duration.Companion.seconds
internal class WcPairSdkDelegate(
private val scope: WcScope,
private val scope: AppCoroutineScope,
private val store: WalletConnectStore,
) : WcSdkObserver {

View file

@ -15,6 +15,7 @@ import com.tangem.domain.walletconnect.model.WcSession
import com.tangem.domain.walletconnect.model.WcSessionDTO
import com.tangem.domain.walletconnect.repository.WcSessionsManager
import com.tangem.domain.wallets.usecase.GetWalletsUseCase
import com.tangem.utils.coroutines.AppCoroutineScope
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.*
@ -32,7 +33,7 @@ internal class DefaultWcSessionsManager(
private val dispatchers: CoroutineDispatcherProvider,
private val wcNetworksConverter: WcNetworksConverter,
private val analytics: AnalyticsEventHandler,
private val scope: WcScope,
private val scope: AppCoroutineScope,
) : WcSessionsManager, WcSdkObserver {
private val onSessionDelete = Channel<Wallet.Model.SessionDelete>(capacity = Channel.BUFFERED)

View file

@ -1,13 +0,0 @@
package com.tangem.data.walletconnect.utils
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
import kotlin.coroutines.CoroutineContext
internal class WcScope(
dispatchers: CoroutineDispatcherProvider,
) : CoroutineScope {
override val coroutineContext: CoroutineContext = SupervisorJob() + dispatchers.io
}

View file

@ -2,6 +2,7 @@ package com.tangem.data.wallets.hot
import com.tangem.common.core.TangemSdkError
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.utils.coroutines.AppCoroutineScope
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.settings.repositories.LegacySettingsRepository
@ -11,10 +12,7 @@ import com.tangem.domain.wallets.repository.WalletsRepository
import com.tangem.hot.sdk.TangemHotSdk
import com.tangem.hot.sdk.exception.WrongPasswordException
import com.tangem.hot.sdk.model.*
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.coroutines.runSuspendCatching
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch
import java.util.concurrent.ConcurrentHashMap
import javax.inject.Inject
@ -27,11 +25,9 @@ class DefaultHotWalletAccessor @Inject constructor(
private val hotWalletPasswordRequester: HotWalletPasswordRequester,
private val walletsRepository: WalletsRepository,
private val legacySettingsRepository: LegacySettingsRepository,
dispatchers: CoroutineDispatcherProvider,
private val scope: AppCoroutineScope,
) : HotWalletAccessor {
private val scope = CoroutineScope(context = SupervisorJob() + dispatchers.io)
private val contextualUnlockHotWallet: ConcurrentHashMap<HotWalletId, UnlockHotWallet?> = ConcurrentHashMap()
override suspend fun signHashes(hotWalletId: HotWalletId, dataToSign: List<DataToSign>): List<SignedData> =