Updated on 2026-08-14

This commit is contained in:
Tangem 2026-06-25 12:48:05 +05:00
parent 0011a40ae3
commit ee599a99c4

View file

@ -18,8 +18,10 @@ import com.tangem.domain.utils.convertToSdkAmount
import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.domain.walletmanager.WalletManagersFacade
import com.tangem.domain.yield.supply.YieldSupplyTransactionRepository import com.tangem.domain.yield.supply.YieldSupplyTransactionRepository
import com.tangem.utils.coroutines.CoroutineDispatcherProvider import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.coroutines.runSuspendCatching
import com.tangem.utils.extensions.orZero import com.tangem.utils.extensions.orZero
import com.tangem.utils.logging.TangemLogger import com.tangem.utils.logging.TangemLogger
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.math.BigDecimal import java.math.BigDecimal
@ -97,7 +99,7 @@ internal class DefaultYieldSupplyTransactionRepository(
cryptoCurrency: CryptoCurrency, cryptoCurrency: CryptoCurrency,
): BigDecimal? = withContext(dispatchers.io) { ): BigDecimal? = withContext(dispatchers.io) {
require(cryptoCurrency is CryptoCurrency.Token) require(cryptoCurrency is CryptoCurrency.Token)
runCatching { runSuspendCatching {
val walletManager = walletManagersFacade.getOrCreateWalletManager( val walletManager = walletManagersFacade.getOrCreateWalletManager(
userWalletId = userWalletId, userWalletId = userWalletId,
blockchain = cryptoCurrency.network.toBlockchain(), blockchain = cryptoCurrency.network.toBlockchain(),
@ -110,7 +112,7 @@ internal class DefaultYieldSupplyTransactionRepository(
decimals = cryptoCurrency.decimals, decimals = cryptoCurrency.decimals,
), ),
) )
}.onFailure { TangemLogger.e("Error", it) }.getOrThrow() }.logErrorUnlessCancellation().getOrThrow()
} }
@Suppress("LongParameterList") @Suppress("LongParameterList")
@ -201,27 +203,27 @@ internal class DefaultYieldSupplyTransactionRepository(
cryptoCurrency: CryptoCurrency, cryptoCurrency: CryptoCurrency,
): String? = withContext(dispatchers.io) { ): String? = withContext(dispatchers.io) {
require(cryptoCurrency is CryptoCurrency.Token) require(cryptoCurrency is CryptoCurrency.Token)
runCatching { runSuspendCatching {
val walletManager = walletManagersFacade.getOrCreateWalletManager( val walletManager = walletManagersFacade.getOrCreateWalletManager(
userWalletId = userWalletId, userWalletId = userWalletId,
blockchain = cryptoCurrency.network.toBlockchain(), blockchain = cryptoCurrency.network.toBlockchain(),
derivationPath = cryptoCurrency.network.derivationPath.value, derivationPath = cryptoCurrency.network.derivationPath.value,
) ?: error("Wallet manager not found") ) ?: error("Wallet manager not found")
walletManager.calculateYieldModuleAddress() walletManager.calculateYieldModuleAddress()
}.onFailure { TangemLogger.e("Error", it) }.getOrThrow() }.logErrorUnlessCancellation().getOrThrow()
} }
override suspend fun getYieldContractAddress(userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency): String? = override suspend fun getYieldContractAddress(userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency): String? =
withContext(dispatchers.io) { withContext(dispatchers.io) {
require(cryptoCurrency is CryptoCurrency.Token) require(cryptoCurrency is CryptoCurrency.Token)
runCatching { runSuspendCatching {
val walletManager = walletManagersFacade.getOrCreateWalletManager( val walletManager = walletManagersFacade.getOrCreateWalletManager(
userWalletId = userWalletId, userWalletId = userWalletId,
blockchain = cryptoCurrency.network.toBlockchain(), blockchain = cryptoCurrency.network.toBlockchain(),
derivationPath = cryptoCurrency.network.derivationPath.value, derivationPath = cryptoCurrency.network.derivationPath.value,
) ?: error("Wallet manager not found") ) ?: error("Wallet manager not found")
walletManager.getYieldModuleAddress() walletManager.getYieldModuleAddress()
}.onFailure { TangemLogger.e("Error", it) }.getOrThrow() }.logErrorUnlessCancellation().getOrThrow()
} }
override suspend fun wrapYieldSwapCallDataWithUpgradeIfNeeded( override suspend fun wrapYieldSwapCallDataWithUpgradeIfNeeded(
@ -242,7 +244,7 @@ internal class DefaultYieldSupplyTransactionRepository(
walletManager: WalletManager, walletManager: WalletManager,
cryptoCurrency: CryptoCurrency.Token, cryptoCurrency: CryptoCurrency.Token,
): YieldSupplyStatus? = withContext(dispatchers.io) { ): YieldSupplyStatus? = withContext(dispatchers.io) {
runCatching { runSuspendCatching {
val sdkSupplyStatus = walletManager.getYieldSupplyStatus(cryptoCurrency.contractAddress) val sdkSupplyStatus = walletManager.getYieldSupplyStatus(cryptoCurrency.contractAddress)
val protocolBalance = if (sdkSupplyStatus?.isActive == true) { val protocolBalance = if (sdkSupplyStatus?.isActive == true) {
walletManager.getEffectiveProtocolBalance( walletManager.getEffectiveProtocolBalance(
@ -269,7 +271,20 @@ internal class DefaultYieldSupplyTransactionRepository(
isAllowedToSpend = isAllowedToSpend, isAllowedToSpend = isAllowedToSpend,
effectiveProtocolBalance = protocolBalance, effectiveProtocolBalance = protocolBalance,
) )
}.onFailure { TangemLogger.e("Error", it) }.getOrNull() }.logErrorUnlessCancellation().getOrThrow()
}
/**
* Logs failures via [TangemLogger] but rethrows coroutine cancellation so a cancelled scope
* (e.g. leaving the yield-supply screen) cancels cleanly instead of being reported as a real
* error and swallowed to `null`. Covers both a raw [CancellationException] and one wrapped by
* the blockchain SDK as [BlockchainSdkError.WrappedThrowable] (carried in [Throwable.cause]),
* which is what `EthereumLikeJsonRpcProvider.post` throws when an in-flight RPC is cancelled.
*/
private fun <T> Result<T>.logErrorUnlessCancellation(): Result<T> = onFailure { error ->
val cancellation = error as? CancellationException ?: error.cause as? CancellationException
if (cancellation != null) throw cancellation
TangemLogger.e("Error", error)
} }
private fun createDeployTransaction( private fun createDeployTransaction(