From 561b7b892cc2327cf0ac03d4f279a2d062859903 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 12 Feb 2025 23:05:18 +0400 Subject: [PATCH] Updated on 2026-08-14 --- .../com/tangem/datasource/di/MoshiModule.kt | 1 + .../datasource/di/StakingStoreModule.kt | 25 ++++++++++--- .../local/token/DefaultStakingBalanceStore.kt | 35 +++++++++--------- .../token/entity/YieldBalanceWrappersDTO.kt | 5 +++ .../token/utils/YieldBalancesSerializer.kt | 36 +++++++++++++++++++ .../data/staking/DefaultStakingRepository.kt | 4 ++- .../data/staking/di/StakingDataModule.kt | 7 ++-- 7 files changed, 88 insertions(+), 25 deletions(-) create mode 100644 core/datasource/src/main/java/com/tangem/datasource/local/token/entity/YieldBalanceWrappersDTO.kt create mode 100644 core/datasource/src/main/java/com/tangem/datasource/local/token/utils/YieldBalancesSerializer.kt diff --git a/core/datasource/src/main/java/com/tangem/datasource/di/MoshiModule.kt b/core/datasource/src/main/java/com/tangem/datasource/di/MoshiModule.kt index f3012c9510..c515d594a1 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/di/MoshiModule.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/di/MoshiModule.kt @@ -56,6 +56,7 @@ class MoshiModule { ExtendedPublicKeysMapAdapter(), CardBackupStatusAdapter(), DerivationPathAdapterWithMigration(), + DateTimeAdapter(), ) val typedAdapters = MoshiJsonConverter.getTangemSdkTypedAdapters() diff --git a/core/datasource/src/main/java/com/tangem/datasource/di/StakingStoreModule.kt b/core/datasource/src/main/java/com/tangem/datasource/di/StakingStoreModule.kt index 34b84bebc9..59b45e9e38 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/di/StakingStoreModule.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/di/StakingStoreModule.kt @@ -1,13 +1,20 @@ package com.tangem.datasource.di +import android.content.Context +import androidx.datastore.core.DataStoreFactory +import androidx.datastore.dataStoreFile +import com.squareup.moshi.Moshi import com.tangem.datasource.local.datastore.RuntimeDataStore import com.tangem.datasource.local.token.* -import com.tangem.datasource.local.token.DefaultStakingBalanceStore -import com.tangem.datasource.local.token.DefaultStakingYieldsStore +import com.tangem.datasource.local.token.utils.YieldBalancesSerializer +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 @@ -22,8 +29,18 @@ internal object StakingStoreModule { @Provides @Singleton - fun provideStakingBalanceStore(): StakingBalanceStore { - return DefaultStakingBalanceStore(dataStore = RuntimeDataStore()) + fun provideStakingBalanceStore( + @NetworkMoshi moshi: Moshi, + @ApplicationContext context: Context, + dispatchers: CoroutineDispatcherProvider, + ): StakingBalanceStore { + return DefaultStakingBalanceStore( + dataStore = DataStoreFactory.create( + serializer = YieldBalancesSerializer(moshi), + produceFile = { context.dataStoreFile(fileName = "yield_balances") }, + scope = CoroutineScope(context = dispatchers.io + SupervisorJob()), + ), + ) } @Provides diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/token/DefaultStakingBalanceStore.kt b/core/datasource/src/main/java/com/tangem/datasource/local/token/DefaultStakingBalanceStore.kt index 985a008daf..28f5e8298f 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/local/token/DefaultStakingBalanceStore.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/local/token/DefaultStakingBalanceStore.kt @@ -1,31 +1,32 @@ package com.tangem.datasource.local.token +import androidx.datastore.core.DataStore import com.tangem.datasource.api.stakekit.models.response.model.YieldBalanceWrapperDTO -import com.tangem.datasource.local.datastore.core.StringKeyDataStore +import com.tangem.datasource.local.token.entity.YieldBalanceWrappersDTO import com.tangem.domain.wallets.models.UserWalletId import com.tangem.utils.extensions.addOrReplace import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.map -import kotlinx.coroutines.sync.Mutex -import kotlinx.coroutines.sync.withLock internal class DefaultStakingBalanceStore( - private val dataStore: StringKeyDataStore>, + private val dataStore: DataStore, ) : StakingBalanceStore { - private val mutex = Mutex() - override fun get(userWalletId: UserWalletId): Flow> { - return dataStore.get(userWalletId.stringValue) + return dataStore.data.map { it[userWalletId.stringValue].orEmpty() } } override suspend fun getSyncOrNull(userWalletId: UserWalletId): Set? { - return dataStore.getSyncOrNull(userWalletId.stringValue) + return dataStore.data.firstOrNull() + ?.get(userWalletId.stringValue) } override suspend fun store(userWalletId: UserWalletId, items: Set) { - mutex.withLock { - dataStore.store(userWalletId.stringValue, items) + dataStore.updateData { current -> + current.toMutableMap().apply { + this[userWalletId.stringValue] = items + } } } @@ -34,7 +35,7 @@ internal class DefaultStakingBalanceStore( address: String, integrationId: String, ): Flow { - return dataStore.get(userWalletId.stringValue) + return get(userWalletId) .map { balances -> balances.firstOrNull { it.integrationId == integrationId && it.addresses.address == address } } @@ -45,7 +46,7 @@ internal class DefaultStakingBalanceStore( address: String, integrationId: String, ): YieldBalanceWrapperDTO? { - return dataStore.getSyncOrNull(userWalletId.stringValue) + return getSyncOrNull(userWalletId) ?.firstOrNull { it.integrationId == integrationId && it.addresses.address == address } } @@ -55,12 +56,10 @@ internal class DefaultStakingBalanceStore( address: String, item: YieldBalanceWrapperDTO, ) { - mutex.withLock { - val balances = dataStore.getSyncOrNull(userWalletId.stringValue) - ?.addOrReplace(item) { it.integrationId == integrationId && it.addresses.address == address } - ?: setOf(item) + val balances = getSyncOrNull(userWalletId) + ?.addOrReplace(item) { it.integrationId == integrationId && it.addresses.address == address } + ?: setOf(item) - dataStore.store(userWalletId.stringValue, balances) - } + store(userWalletId, balances) } } \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/token/entity/YieldBalanceWrappersDTO.kt b/core/datasource/src/main/java/com/tangem/datasource/local/token/entity/YieldBalanceWrappersDTO.kt new file mode 100644 index 0000000000..2490b5a01b --- /dev/null +++ b/core/datasource/src/main/java/com/tangem/datasource/local/token/entity/YieldBalanceWrappersDTO.kt @@ -0,0 +1,5 @@ +package com.tangem.datasource.local.token.entity + +import com.tangem.datasource.api.stakekit.models.response.model.YieldBalanceWrapperDTO + +internal typealias YieldBalanceWrappersDTO = Map> \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/token/utils/YieldBalancesSerializer.kt b/core/datasource/src/main/java/com/tangem/datasource/local/token/utils/YieldBalancesSerializer.kt new file mode 100644 index 0000000000..421fd14414 --- /dev/null +++ b/core/datasource/src/main/java/com/tangem/datasource/local/token/utils/YieldBalancesSerializer.kt @@ -0,0 +1,36 @@ +package com.tangem.datasource.local.token.utils + +import androidx.datastore.core.Serializer +import com.squareup.moshi.Moshi +import com.squareup.moshi.Types +import com.tangem.datasource.api.stakekit.models.response.model.YieldBalanceWrapperDTO +import com.tangem.datasource.local.token.entity.YieldBalanceWrappersDTO +import java.io.InputStream +import java.io.OutputStream + +internal class YieldBalancesSerializer(moshi: Moshi) : Serializer { + + private val adapter by lazy { + val type = Types.newParameterizedType( + Map::class.java, + String::class.java, + Types.newParameterizedType(Set::class.java, YieldBalanceWrapperDTO::class.java), + ) + + moshi.adapter(type) + } + + override val defaultValue: YieldBalanceWrappersDTO = emptyMap() + + override suspend fun readFrom(input: InputStream): YieldBalanceWrappersDTO { + return input.bufferedReader().use { reader -> + adapter.fromJson(reader.readText()) ?: defaultValue + } + } + + override suspend fun writeTo(t: YieldBalanceWrappersDTO, output: OutputStream) { + output.bufferedWriter().use { writer -> + writer.write(adapter.toJson(t)) + } + } +} \ No newline at end of file diff --git a/data/staking/src/main/java/com/tangem/data/staking/DefaultStakingRepository.kt b/data/staking/src/main/java/com/tangem/data/staking/DefaultStakingRepository.kt index 90f71a6274..4694b9f4d6 100644 --- a/data/staking/src/main/java/com/tangem/data/staking/DefaultStakingRepository.kt +++ b/data/staking/src/main/java/com/tangem/data/staking/DefaultStakingRepository.kt @@ -484,7 +484,9 @@ internal class DefaultStakingRepository( userWalletId: UserWalletId, cryptoCurrencies: List, ): Flow { - TODO("Will be implemented in [REDACTED_TASK_KEY]") + return stakingBalanceStore.get(userWalletId) + .map(yieldBalanceListConverter::convert) + .flowOn(dispatchers.io) } override fun getMultiYieldBalanceUpdatesLegacy( diff --git a/data/staking/src/main/java/com/tangem/data/staking/di/StakingDataModule.kt b/data/staking/src/main/java/com/tangem/data/staking/di/StakingDataModule.kt index 3e777df680..43c7003ba5 100644 --- a/data/staking/src/main/java/com/tangem/data/staking/di/StakingDataModule.kt +++ b/data/staking/src/main/java/com/tangem/data/staking/di/StakingDataModule.kt @@ -4,7 +4,7 @@ import com.squareup.moshi.Moshi import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.core.configtoggle.feature.FeatureTogglesManager import com.tangem.data.common.cache.CacheRegistry -import com.tangem.data.staking.* +import com.tangem.data.staking.DefaultStakingActionRepository import com.tangem.data.staking.DefaultStakingErrorResolver import com.tangem.data.staking.DefaultStakingRepository import com.tangem.data.staking.DefaultStakingTransactionHashRepository @@ -17,7 +17,10 @@ import com.tangem.datasource.local.preferences.AppPreferencesStore import com.tangem.datasource.local.token.StakingActionsStore import com.tangem.datasource.local.token.StakingBalanceStore import com.tangem.datasource.local.token.StakingYieldsStore -import com.tangem.domain.staking.repositories.* +import com.tangem.domain.staking.repositories.StakingActionRepository +import com.tangem.domain.staking.repositories.StakingErrorResolver +import com.tangem.domain.staking.repositories.StakingRepository +import com.tangem.domain.staking.repositories.StakingTransactionHashRepository import com.tangem.domain.staking.toggles.StakingFeatureToggles import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.domain.wallets.usecase.GetUserWalletUseCase