Updated on 2026-08-14

This commit is contained in:
Tangem 2025-10-07 19:47:17 +05:00
parent 4534ceb54b
commit 480bfdd412
8 changed files with 112 additions and 0 deletions

View file

@ -114,4 +114,22 @@ internal object YieldSupplyDomainModule {
yieldSupplyRepository = yieldSupplyRepository,
)
}
@Provides
@Singleton
fun provideYieldSupplyActivateUseCase(yieldSupplyRepository: YieldSupplyRepository): YieldSupplyActivateUseCase {
return YieldSupplyActivateUseCase(
yieldSupplyRepository = yieldSupplyRepository,
)
}
@Provides
@Singleton
fun provideYieldSupplyDeactivateUseCase(
yieldSupplyRepository: YieldSupplyRepository,
): YieldSupplyDeactivateUseCase {
return YieldSupplyDeactivateUseCase(
yieldSupplyRepository = yieldSupplyRepository,
)
}
}

View file

@ -11,6 +11,7 @@ import com.tangem.data.yield.supply.converters.YieldMarketTokenConverter
import com.tangem.datasource.api.tangemTech.YieldSupplyApi
import com.tangem.data.yield.supply.converters.YieldTokenStatusConverter
import com.tangem.data.yield.supply.converters.YieldTokenChartConverter
import com.tangem.datasource.api.tangemTech.models.YieldSupplyChangeTokenStatusBody
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.walletmanager.WalletManagersFacade
@ -73,6 +74,30 @@ internal class DefaultYieldSupplyRepository(
(walletManager as? YieldSupplyProvider)?.isSupported() ?: false
}
override suspend fun activateProtocol(cryptoCurrencyToken: CryptoCurrency.Token): Boolean =
withContext(dispatchers.io) {
val chainId = Blockchain.fromNetworkId(cryptoCurrencyToken.network.backendId)?.getChainId()
?: error("Chain id is required for evm's")
yieldSupplyApi.activateYieldModule(
YieldSupplyChangeTokenStatusBody(
tokenAddress = cryptoCurrencyToken.contractAddress,
chainId = chainId,
),
).getOrThrow().isActive
}
override suspend fun deactivateProtocol(cryptoCurrencyToken: CryptoCurrency.Token): Boolean =
withContext(dispatchers.io) {
val chainId = Blockchain.fromNetworkId(cryptoCurrencyToken.network.backendId)?.getChainId()
?: error("Chain id is required for evm's")
yieldSupplyApi.deactivateYieldModule(
YieldSupplyChangeTokenStatusBody(
tokenAddress = cryptoCurrencyToken.contractAddress,
chainId = chainId,
),
).getOrThrow().isActive
}
private fun List<YieldMarketToken>.enrichNetworkIds(): List<YieldMarketToken> {
val chainIdMap = Blockchain.entries.associate { it.getChainId() to it.toNetworkId() }
return this.map { token ->

View file

@ -38,4 +38,23 @@ interface YieldSupplyRepository {
suspend fun getTokenChart(cryptoCurrencyToken: CryptoCurrency.Token): YieldSupplyMarketChartData
suspend fun isYieldSupplySupported(userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency): Boolean
/**
* Activate yield protocol for the specified token.
*
* Returns whether the token is active after the operation completes.
* May throw on network/backend errors or if required chain id cannot be resolved.
*/
@Throws
suspend fun activateProtocol(cryptoCurrencyToken: CryptoCurrency.Token): Boolean
/**
* Deactivate yield protocol for the specified token.
*
* Returns whether the token is active after the operation completes
* (expected to be false when deactivation succeeds). May throw on
* network/backend errors or if required chain id cannot be resolved.
*/
@Throws
suspend fun deactivateProtocol(cryptoCurrencyToken: CryptoCurrency.Token): Boolean
}

View file

@ -0,0 +1,14 @@
package com.tangem.domain.yield.supply.usecase
import arrow.core.Either
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.yield.supply.YieldSupplyRepository
class YieldSupplyActivateUseCase(
private val yieldSupplyRepository: YieldSupplyRepository,
) {
suspend operator fun invoke(cryptoCurrencyToken: CryptoCurrency.Token): Either<Throwable, Boolean> = Either.catch {
yieldSupplyRepository.activateProtocol(cryptoCurrencyToken)
}
}

View file

@ -0,0 +1,14 @@
package com.tangem.domain.yield.supply.usecase
import arrow.core.Either
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.yield.supply.YieldSupplyRepository
class YieldSupplyDeactivateUseCase(
private val yieldSupplyRepository: YieldSupplyRepository,
) {
suspend operator fun invoke(cryptoCurrencyToken: CryptoCurrency.Token): Either<Throwable, Boolean> = Either.catch {
yieldSupplyRepository.deactivateProtocol(cryptoCurrencyToken)
}
}

View file

@ -16,6 +16,8 @@ import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.tokens.FetchCurrencyStatusUseCase
import com.tangem.domain.tokens.GetSingleCryptoCurrencyStatusUseCase
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
import com.tangem.domain.yield.supply.usecase.YieldSupplyActivateUseCase
import com.tangem.domain.yield.supply.usecase.YieldSupplyDeactivateUseCase
import com.tangem.domain.yield.supply.usecase.YieldSupplyGetTokenStatusUseCase
import com.tangem.domain.yield.supply.usecase.YieldSupplyIsAvailableUseCase
import com.tangem.features.yield.supply.api.YieldSupplyComponent
@ -47,6 +49,8 @@ internal class YieldSupplyModel @Inject constructor(
private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
private val yieldSupplyGetTokenStatusUseCase: YieldSupplyGetTokenStatusUseCase,
private val yieldSupplyIsAvailableUseCase: YieldSupplyIsAvailableUseCase,
private val yieldSupplyActivateUseCase: YieldSupplyActivateUseCase,
private val yieldSupplyDeactivateUseCase: YieldSupplyDeactivateUseCase,
) : Model(), YieldSupplyClickIntents {
private val params = paramsContainer.require<YieldSupplyComponent.Params>()
@ -162,6 +166,7 @@ internal class YieldSupplyModel @Inject constructor(
val yieldTransaction = cryptoCurrencyStatus.value.pendingTransactions.firstOrNull {
it.type is TxInfo.TransactionType.YieldSupply
}?.type as? TxInfo.TransactionType.YieldSupply
sendInfoAboutProtocolStatus(yieldSupplyStatus?.isActive == true)
val yieldSupplyUM = when {
hasActiveTransaction && yieldTransaction != null -> {
@ -193,6 +198,17 @@ internal class YieldSupplyModel @Inject constructor(
}
}
private fun sendInfoAboutProtocolStatus(isActivated: Boolean) {
val token = cryptoCurrency as? CryptoCurrency.Token ?: return
modelScope.launch(dispatchers.default) {
if (isActivated) {
yieldSupplyActivateUseCase(token)
} else {
yieldSupplyDeactivateUseCase(token)
}
}
}
private companion object {
const val PROCESSING_UPDATE_DELAY = 10_000L
}

View file

@ -19,6 +19,7 @@ import com.tangem.domain.tokens.GetFeePaidCryptoCurrencyStatusSyncUseCase
import com.tangem.domain.tokens.GetSingleCryptoCurrencyStatusUseCase
import com.tangem.domain.transaction.usecase.SendTransactionUseCase
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
import com.tangem.domain.yield.supply.usecase.YieldSupplyActivateUseCase
import com.tangem.domain.yield.supply.usecase.YieldSupplyEstimateEnterFeeUseCase
import com.tangem.domain.yield.supply.usecase.YieldSupplyGetTokenStatusUseCase
import com.tangem.domain.yield.supply.usecase.YieldSupplyStartEarningUseCase
@ -58,6 +59,7 @@ internal class YieldSupplyStartEarningModel @Inject constructor(
private val yieldSupplyNotificationsUpdateTrigger: YieldSupplyNotificationsUpdateTrigger,
private val fetchCurrencyStatusUseCase: FetchCurrencyStatusUseCase,
private val yieldSupplyAlertFactory: YieldSupplyAlertFactory,
private val yieldSupplyActivateUseCase: YieldSupplyActivateUseCase,
private val yieldSupplyGetTokenStatusUseCase: YieldSupplyGetTokenStatusUseCase,
) : Model(), YieldSupplyNotificationsComponent.ModelCallback {
@ -206,6 +208,7 @@ internal class YieldSupplyStartEarningModel @Inject constructor(
},
ifRight = {
fetchCurrencyStatusUseCase(userWalletId = userWallet.walletId, cryptoCurrency.id)
yieldSupplyActivateUseCase(cryptoCurrency as CryptoCurrency.Token)
modelScope.launch {
params.callback.onTransactionSent()
}

View file

@ -15,6 +15,7 @@ import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.tokens.GetFeePaidCryptoCurrencyStatusSyncUseCase
import com.tangem.domain.transaction.usecase.GetFeeUseCase
import com.tangem.domain.transaction.usecase.SendTransactionUseCase
import com.tangem.domain.yield.supply.usecase.YieldSupplyDeactivateUseCase
import com.tangem.domain.yield.supply.usecase.YieldSupplyStopEarningUseCase
import com.tangem.features.yield.supply.impl.R
import com.tangem.features.yield.supply.impl.common.YieldSupplyAlertFactory
@ -49,6 +50,7 @@ internal class YieldSupplyStopEarningModel @Inject constructor(
private val urlOpener: UrlOpener,
private val yieldSupplyNotificationsUpdateTrigger: YieldSupplyNotificationsUpdateTrigger,
private val yieldSupplyAlertFactory: YieldSupplyAlertFactory,
private val yieldSupplyDeactivateUseCase: YieldSupplyDeactivateUseCase,
) : Model(), YieldSupplyNotificationsComponent.ModelCallback {
private val params: YieldSupplyStopEarningComponent.Params = paramsContainer.require()
@ -134,6 +136,7 @@ internal class YieldSupplyStopEarningModel @Inject constructor(
)
},
ifRight = {
yieldSupplyDeactivateUseCase(cryptoCurrency as CryptoCurrency.Token)
params.callback.onTransactionSent()
},
)