From e49a9befc7d7d282f724b759b17ef65320b58c3e Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 9 Sep 2024 10:10:35 +0300 Subject: [PATCH] Updated on 2026-08-14 --- .../main/java/com/tangem/tap/MainActivity.kt | 2 +- .../tap/di/domain/StakingDomainModule.kt | 13 +-- data/staking/build.gradle.kts | 1 + .../data/staking/DefaultStakingRepository.kt | 59 +------------ ...DefaultStakingTransactionHashRepository.kt | 83 +++++++++++++++++++ .../data/staking/di/StakingDataModule.kt | 26 ++++-- .../staking/SaveUnsubmittedHashUseCase.kt | 6 +- .../staking/SendUnsubmittedHashesUseCase.kt | 6 +- .../domain/staking/SubmitHashUseCase.kt | 6 +- .../staking/repositories/StakingRepository.kt | 7 -- .../StakingTransactionHashRepository.kt | 12 +++ .../repository/MockStakingRepository.kt | 13 --- 12 files changed, 137 insertions(+), 97 deletions(-) create mode 100644 data/staking/src/main/java/com/tangem/data/staking/DefaultStakingTransactionHashRepository.kt create mode 100644 domain/staking/src/main/java/com/tangem/domain/staking/repositories/StakingTransactionHashRepository.kt diff --git a/app/src/main/java/com/tangem/tap/MainActivity.kt b/app/src/main/java/com/tangem/tap/MainActivity.kt index f9888910fa..7735974a6d 100644 --- a/app/src/main/java/com/tangem/tap/MainActivity.kt +++ b/app/src/main/java/com/tangem/tap/MainActivity.kt @@ -583,8 +583,8 @@ class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbac private fun sendStakingUnsubmittedHashes() { lifecycleScope.launch { sendUnsubmittedHashesUseCase.invoke() - .onRight { Timber.d("Submitting hashes succeeded") } .onLeft { Timber.e(it.toString()) } + .onRight { Timber.d("Submitting hashes succeeded") } } } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/di/domain/StakingDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/StakingDomainModule.kt index 388a7df7b7..2c64513e3b 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/StakingDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/StakingDomainModule.kt @@ -3,6 +3,7 @@ package com.tangem.tap.di.domain import com.tangem.domain.staking.* import com.tangem.domain.staking.repositories.StakingErrorResolver import com.tangem.domain.staking.repositories.StakingRepository +import com.tangem.domain.staking.repositories.StakingTransactionHashRepository import dagger.Module import dagger.Provides import dagger.hilt.InstallIn @@ -112,11 +113,11 @@ internal object StakingDomainModule { @Provides @Singleton fun provideSubmitHashUseCase( - stakingRepository: StakingRepository, + stakingTransactionHashRepository: StakingTransactionHashRepository, stakingErrorResolver: StakingErrorResolver, ): SubmitHashUseCase { return SubmitHashUseCase( - stakingRepository = stakingRepository, + stakingTransactionHashRepository = stakingTransactionHashRepository, stakingErrorResolver = stakingErrorResolver, ) } @@ -124,11 +125,11 @@ internal object StakingDomainModule { @Provides @Singleton fun provideSaveUnsubmittedHashUseCase( - stakingRepository: StakingRepository, + stakingTransactionHashRepository: StakingTransactionHashRepository, stakingErrorResolver: StakingErrorResolver, ): SaveUnsubmittedHashUseCase { return SaveUnsubmittedHashUseCase( - stakingRepository = stakingRepository, + stakingTransactionHashRepository = stakingTransactionHashRepository, stakingErrorResolver = stakingErrorResolver, ) } @@ -136,11 +137,11 @@ internal object StakingDomainModule { @Provides @Singleton fun provideSendUnsubmittedHashesUseCase( - stakingRepository: StakingRepository, + stakingTransactionHashRepository: StakingTransactionHashRepository, stakingErrorResolver: StakingErrorResolver, ): SendUnsubmittedHashesUseCase { return SendUnsubmittedHashesUseCase( - stakingRepository = stakingRepository, + stakingTransactionHashRepository = stakingTransactionHashRepository, stakingErrorResolver = stakingErrorResolver, ) } diff --git a/data/staking/build.gradle.kts b/data/staking/build.gradle.kts index 4a9ba3d819..f79c7c6109 100644 --- a/data/staking/build.gradle.kts +++ b/data/staking/build.gradle.kts @@ -44,6 +44,7 @@ dependencies { implementation(deps.kotlin.immutable.collections) implementation(deps.moshi) implementation(deps.moshi.kotlin) + implementation(deps.timber) implementation(projects.libs.blockchainSdk) implementation(projects.libs.crypto) 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 65b43686b3..f1c4732032 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 @@ -26,9 +26,6 @@ import com.tangem.datasource.api.stakekit.StakeKitApi import com.tangem.datasource.api.stakekit.models.request.* import com.tangem.datasource.api.stakekit.models.response.model.YieldBalanceWrapperDTO import com.tangem.datasource.api.stakekit.models.response.model.transaction.tron.TronStakeKitTransaction -import com.tangem.datasource.local.preferences.AppPreferencesStore -import com.tangem.datasource.local.preferences.PreferencesKeys -import com.tangem.datasource.local.preferences.utils.getObjectListSync import com.tangem.datasource.local.token.StakingBalanceStore import com.tangem.datasource.local.token.StakingYieldsStore import com.tangem.domain.core.lce.LceFlow @@ -36,7 +33,10 @@ import com.tangem.domain.core.lce.lceFlow import com.tangem.domain.staking.model.StakingApproval import com.tangem.domain.staking.model.StakingAvailability import com.tangem.domain.staking.model.StakingEntryInfo -import com.tangem.domain.staking.model.UnsubmittedTransactionMetadata +import com.tangem.domain.staking.model.stakekit.NetworkType +import com.tangem.domain.staking.model.stakekit.Yield +import com.tangem.domain.staking.model.stakekit.YieldBalance +import com.tangem.domain.staking.model.stakekit.YieldBalanceList import com.tangem.domain.staking.model.stakekit.* import com.tangem.domain.staking.model.stakekit.action.StakingAction import com.tangem.domain.staking.model.stakekit.action.StakingActionCommonType @@ -54,7 +54,6 @@ import com.tangem.features.staking.api.featuretoggles.StakingFeatureToggles import com.tangem.utils.coroutines.CoroutineDispatcherProvider import com.tangem.utils.extensions.orZero import com.tangem.lib.crypto.BlockchainUtils.isSolana -import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -62,7 +61,6 @@ import kotlinx.coroutines.withContext @Suppress("LargeClass", "LongParameterList", "TooManyFunctions") internal class DefaultStakingRepository( private val stakeKitApi: StakeKitApi, - private val appPreferencesStore: AppPreferencesStore, private val stakingYieldsStore: StakingYieldsStore, private val stakingBalanceStore: StakingBalanceStore, private val cacheRegistry: CacheRegistry, @@ -464,55 +462,6 @@ internal class DefaultStakingRepository( } } - override suspend fun submitHash(transactionId: String, transactionHash: String) { - withContext(dispatchers.io) { - stakeKitApi.submitTransactionHash( - transactionId = transactionId, - body = SubmitTransactionHashRequestBody( - hash = transactionHash, - ), - ) - } - } - - override suspend fun storeUnsubmittedHash(unsubmittedTransactionMetadata: UnsubmittedTransactionMetadata) { - withContext(dispatchers.io) { - appPreferencesStore.editData { preferences -> - val savedTransactions = preferences.getObjectListOrDefault( - key = PreferencesKeys.UNSUBMITTED_TRANSACTIONS_KEY, - default = emptyList(), - ) - - preferences.setObjectList( - key = PreferencesKeys.UNSUBMITTED_TRANSACTIONS_KEY, - value = savedTransactions + unsubmittedTransactionMetadata, - ) - } - } - } - - override suspend fun sendUnsubmittedHashes() { - withContext(NonCancellable) { - val savedTransactions = appPreferencesStore.getObjectListSync( - key = PreferencesKeys.UNSUBMITTED_TRANSACTIONS_KEY, - ) - - savedTransactions.forEach { - stakeKitApi.submitTransactionHash( - transactionId = it.transactionId, - body = SubmitTransactionHashRequestBody(hash = it.transactionHash), - ) - } - - appPreferencesStore.editData { mutablePreferences -> - mutablePreferences.setObjectList( - key = PreferencesKeys.UNSUBMITTED_TRANSACTIONS_KEY, - value = emptyList(), - ) - } - } - } - override suspend fun isAnyTokenStaked(userWalletId: UserWalletId): Boolean { return withContext(dispatchers.io) { stakingBalanceStore.getSyncOrNull(userWalletId) diff --git a/data/staking/src/main/java/com/tangem/data/staking/DefaultStakingTransactionHashRepository.kt b/data/staking/src/main/java/com/tangem/data/staking/DefaultStakingTransactionHashRepository.kt new file mode 100644 index 0000000000..0d12489648 --- /dev/null +++ b/data/staking/src/main/java/com/tangem/data/staking/DefaultStakingTransactionHashRepository.kt @@ -0,0 +1,83 @@ +package com.tangem.data.staking + +import com.tangem.datasource.api.stakekit.StakeKitApi +import com.tangem.datasource.api.stakekit.models.request.* +import com.tangem.datasource.local.preferences.AppPreferencesStore +import com.tangem.datasource.local.preferences.PreferencesKeys +import com.tangem.datasource.local.preferences.utils.getObjectListSync +import com.tangem.domain.staking.model.UnsubmittedTransactionMetadata +import com.tangem.domain.staking.repositories.StakingTransactionHashRepository +import com.tangem.utils.coroutines.CoroutineDispatcherProvider +import kotlinx.coroutines.withContext +import timber.log.Timber + +internal class DefaultStakingTransactionHashRepository( + private val stakeKitApi: StakeKitApi, + private val appPreferencesStore: AppPreferencesStore, + private val dispatchers: CoroutineDispatcherProvider, +) : StakingTransactionHashRepository { + + override suspend fun submitHash(transactionId: String, transactionHash: String) { + withContext(dispatchers.io) { + stakeKitApi.submitTransactionHash( + transactionId = transactionId, + body = SubmitTransactionHashRequestBody( + hash = transactionHash, + ), + ) + } + } + + override suspend fun storeUnsubmittedHash(unsubmittedTransactionMetadata: UnsubmittedTransactionMetadata) { + withContext(dispatchers.io) { + appPreferencesStore.editData { preferences -> + val savedTransactions = preferences.getObjectListOrDefault( + key = PreferencesKeys.UNSUBMITTED_TRANSACTIONS_KEY, + default = emptyList(), + ) + + preferences.setObjectList( + key = PreferencesKeys.UNSUBMITTED_TRANSACTIONS_KEY, + value = savedTransactions + unsubmittedTransactionMetadata, + ) + } + } + } + + override suspend fun sendUnsubmittedHashes() { + withContext(dispatchers.io) { + val savedTransactions = appPreferencesStore.getObjectListSync( + key = PreferencesKeys.UNSUBMITTED_TRANSACTIONS_KEY, + ) + + savedTransactions.forEach { transaction -> + try { + stakeKitApi.submitTransactionHash( + transactionId = transaction.transactionId, + body = SubmitTransactionHashRequestBody(hash = transaction.transactionHash), + ) + + appPreferencesStore.editData { mutablePreferences -> + val updatedTransactions = + mutablePreferences.getObjectListOrDefault( + key = PreferencesKeys.UNSUBMITTED_TRANSACTIONS_KEY, + default = emptyList(), + ).filterNot { it.transactionId == transaction.transactionId } + + mutablePreferences.setObjectList( + key = PreferencesKeys.UNSUBMITTED_TRANSACTIONS_KEY, + value = updatedTransactions, + ) + } + } catch (e: Exception) { + val logMessage = buildString { + append("Error while submitting transaction with\n") + append("StakeKit id = ${transaction.transactionId} and\n") + append("transaction hash = ${transaction.transactionHash}") + } + Timber.e(logMessage) + } + } + } + } +} \ No newline at end of file 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 fc2baff6dd..cb8d518895 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,6 +4,7 @@ import com.squareup.moshi.Moshi import com.tangem.data.common.cache.CacheRegistry import com.tangem.data.staking.DefaultStakingErrorResolver import com.tangem.data.staking.DefaultStakingRepository +import com.tangem.data.staking.DefaultStakingTransactionHashRepository import com.tangem.data.staking.converters.error.StakeKitErrorConverter import com.tangem.datasource.api.stakekit.StakeKitApi import com.tangem.datasource.api.stakekit.models.response.model.error.StakeKitErrorResponse @@ -13,6 +14,7 @@ import com.tangem.datasource.local.token.StakingBalanceStore import com.tangem.datasource.local.token.StakingYieldsStore 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.walletmanager.WalletManagersFacade import com.tangem.domain.wallets.usecase.GetUserWalletUseCase import com.tangem.features.staking.api.featuretoggles.StakingFeatureToggles @@ -31,23 +33,21 @@ internal object StakingDataModule { @Singleton fun provideStakingRepository( stakeKitApi: StakeKitApi, - appPreferencesStore: AppPreferencesStore, - stakingTokenStore: StakingYieldsStore, + stakingYieldsStore: StakingYieldsStore, stakingBalanceStore: StakingBalanceStore, + cacheRegistry: CacheRegistry, dispatchers: CoroutineDispatcherProvider, stakingFeatureToggle: StakingFeatureToggles, - cacheRegistry: CacheRegistry, walletManagersFacade: WalletManagersFacade, getUserWalletUseCase: GetUserWalletUseCase, @NetworkMoshi moshi: Moshi, ): StakingRepository { return DefaultStakingRepository( stakeKitApi = stakeKitApi, - appPreferencesStore = appPreferencesStore, - stakingYieldsStore = stakingTokenStore, + stakingYieldsStore = stakingYieldsStore, stakingBalanceStore = stakingBalanceStore, - dispatchers = dispatchers, cacheRegistry = cacheRegistry, + dispatchers = dispatchers, stakingFeatureToggle = stakingFeatureToggle, walletManagersFacade = walletManagersFacade, getUserWalletUseCase = getUserWalletUseCase, @@ -55,6 +55,20 @@ internal object StakingDataModule { ) } + @Provides + @Singleton + fun StakingTransactionHashRepository( + stakeKitApi: StakeKitApi, + appPreferencesStore: AppPreferencesStore, + dispatchers: CoroutineDispatcherProvider, + ): StakingTransactionHashRepository { + return DefaultStakingTransactionHashRepository( + stakeKitApi = stakeKitApi, + appPreferencesStore = appPreferencesStore, + dispatchers = dispatchers, + ) + } + @Provides @Singleton internal fun provideStakingErrorResolver(@NetworkMoshi moshi: Moshi): StakingErrorResolver { diff --git a/domain/staking/src/main/java/com/tangem/domain/staking/SaveUnsubmittedHashUseCase.kt b/domain/staking/src/main/java/com/tangem/domain/staking/SaveUnsubmittedHashUseCase.kt index 0a83c395cb..abfeab0d56 100644 --- a/domain/staking/src/main/java/com/tangem/domain/staking/SaveUnsubmittedHashUseCase.kt +++ b/domain/staking/src/main/java/com/tangem/domain/staking/SaveUnsubmittedHashUseCase.kt @@ -4,19 +4,19 @@ import arrow.core.Either import com.tangem.domain.staking.model.stakekit.StakingError import com.tangem.domain.staking.model.UnsubmittedTransactionMetadata import com.tangem.domain.staking.repositories.StakingErrorResolver -import com.tangem.domain.staking.repositories.StakingRepository +import com.tangem.domain.staking.repositories.StakingTransactionHashRepository /** * Use case for saving hash that failed to submit during staking confirmation */ class SaveUnsubmittedHashUseCase( - private val stakingRepository: StakingRepository, + private val stakingTransactionHashRepository: StakingTransactionHashRepository, private val stakingErrorResolver: StakingErrorResolver, ) { suspend operator fun invoke(transactionId: String, transactionHash: String): Either { return Either.catch { - stakingRepository.storeUnsubmittedHash( + stakingTransactionHashRepository.storeUnsubmittedHash( unsubmittedTransactionMetadata = UnsubmittedTransactionMetadata( transactionId = transactionId, transactionHash = transactionHash, diff --git a/domain/staking/src/main/java/com/tangem/domain/staking/SendUnsubmittedHashesUseCase.kt b/domain/staking/src/main/java/com/tangem/domain/staking/SendUnsubmittedHashesUseCase.kt index 95f3ad9eea..3564651d9f 100644 --- a/domain/staking/src/main/java/com/tangem/domain/staking/SendUnsubmittedHashesUseCase.kt +++ b/domain/staking/src/main/java/com/tangem/domain/staking/SendUnsubmittedHashesUseCase.kt @@ -3,19 +3,19 @@ package com.tangem.domain.staking import arrow.core.Either import com.tangem.domain.staking.model.stakekit.StakingError import com.tangem.domain.staking.repositories.StakingErrorResolver -import com.tangem.domain.staking.repositories.StakingRepository +import com.tangem.domain.staking.repositories.StakingTransactionHashRepository /** * Use case for commiting hashes that failed to submit during staking confirmation */ class SendUnsubmittedHashesUseCase( - private val stakingRepository: StakingRepository, + private val stakingTransactionHashRepository: StakingTransactionHashRepository, private val stakingErrorResolver: StakingErrorResolver, ) { suspend operator fun invoke(): Either { return Either - .catch { stakingRepository.sendUnsubmittedHashes() } + .catch { stakingTransactionHashRepository.sendUnsubmittedHashes() } .mapLeft { stakingErrorResolver.resolve(it) } } } \ No newline at end of file diff --git a/domain/staking/src/main/java/com/tangem/domain/staking/SubmitHashUseCase.kt b/domain/staking/src/main/java/com/tangem/domain/staking/SubmitHashUseCase.kt index d810cfac8c..83d1b151b7 100644 --- a/domain/staking/src/main/java/com/tangem/domain/staking/SubmitHashUseCase.kt +++ b/domain/staking/src/main/java/com/tangem/domain/staking/SubmitHashUseCase.kt @@ -3,20 +3,20 @@ package com.tangem.domain.staking import arrow.core.Either import com.tangem.domain.staking.model.stakekit.StakingError import com.tangem.domain.staking.repositories.StakingErrorResolver -import com.tangem.domain.staking.repositories.StakingRepository +import com.tangem.domain.staking.repositories.StakingTransactionHashRepository /** * Use case for submitting transaction hash to stakekit */ class SubmitHashUseCase( - private val stakingRepository: StakingRepository, + private val stakingTransactionHashRepository: StakingTransactionHashRepository, private val stakingErrorResolver: StakingErrorResolver, ) { suspend fun submitHash(transactionId: String, transactionHash: String): Either { return Either .catch { - stakingRepository.submitHash( + stakingTransactionHashRepository.submitHash( transactionId = transactionId, transactionHash = transactionHash, ) diff --git a/domain/staking/src/main/java/com/tangem/domain/staking/repositories/StakingRepository.kt b/domain/staking/src/main/java/com/tangem/domain/staking/repositories/StakingRepository.kt index aa35ac2b58..ba93d3e3cb 100644 --- a/domain/staking/src/main/java/com/tangem/domain/staking/repositories/StakingRepository.kt +++ b/domain/staking/src/main/java/com/tangem/domain/staking/repositories/StakingRepository.kt @@ -6,7 +6,6 @@ import com.tangem.domain.core.lce.LceFlow import com.tangem.domain.staking.model.StakingApproval import com.tangem.domain.staking.model.StakingAvailability import com.tangem.domain.staking.model.StakingEntryInfo -import com.tangem.domain.staking.model.UnsubmittedTransactionMetadata import com.tangem.domain.staking.model.stakekit.Yield import com.tangem.domain.staking.model.stakekit.YieldBalance import com.tangem.domain.staking.model.stakekit.YieldBalanceList @@ -75,12 +74,6 @@ interface StakingRepository { transactionId: String, ): Pair - suspend fun submitHash(transactionId: String, transactionHash: String) - - suspend fun storeUnsubmittedHash(unsubmittedTransactionMetadata: UnsubmittedTransactionMetadata) - - suspend fun sendUnsubmittedHashes() - /** Returns staking approval */ fun getStakingApproval(cryptoCurrency: CryptoCurrency): StakingApproval diff --git a/domain/staking/src/main/java/com/tangem/domain/staking/repositories/StakingTransactionHashRepository.kt b/domain/staking/src/main/java/com/tangem/domain/staking/repositories/StakingTransactionHashRepository.kt new file mode 100644 index 0000000000..be75380a84 --- /dev/null +++ b/domain/staking/src/main/java/com/tangem/domain/staking/repositories/StakingTransactionHashRepository.kt @@ -0,0 +1,12 @@ +package com.tangem.domain.staking.repositories + +import com.tangem.domain.staking.model.UnsubmittedTransactionMetadata + +interface StakingTransactionHashRepository { + + suspend fun submitHash(transactionId: String, transactionHash: String) + + suspend fun storeUnsubmittedHash(unsubmittedTransactionMetadata: UnsubmittedTransactionMetadata) + + suspend fun sendUnsubmittedHashes() +} \ No newline at end of file diff --git a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockStakingRepository.kt b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockStakingRepository.kt index f9a6856ac9..cc3fc8d8b2 100644 --- a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockStakingRepository.kt +++ b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockStakingRepository.kt @@ -8,7 +8,6 @@ import com.tangem.domain.core.lce.lceFlow import com.tangem.domain.staking.model.StakingApproval import com.tangem.domain.staking.model.StakingAvailability import com.tangem.domain.staking.model.StakingEntryInfo -import com.tangem.domain.staking.model.UnsubmittedTransactionMetadata import com.tangem.domain.staking.model.stakekit.* import com.tangem.domain.staking.model.stakekit.action.StakingAction import com.tangem.domain.staking.model.stakekit.action.StakingActionStatus @@ -239,18 +238,6 @@ class MockStakingRepository : StakingRepository { status = TransactionStatus.Unconfirmed, ) - override suspend fun submitHash(transactionId: String, transactionHash: String) { - /* no-op */ - } - - override suspend fun storeUnsubmittedHash(unsubmittedTransactionMetadata: UnsubmittedTransactionMetadata) { - /* no-op */ - } - - override suspend fun sendUnsubmittedHashes() { - /* no-op */ - } - override fun getStakingApproval(cryptoCurrency: CryptoCurrency): StakingApproval = StakingApproval.Empty override suspend fun isAnyTokenStaked(userWalletId: UserWalletId): Boolean = false