Updated on 2026-08-14

This commit is contained in:
Tangem 2025-09-26 19:10:22 +05:00
parent 3fd8b110ef
commit 1d06981060
19 changed files with 190 additions and 42 deletions

View file

@ -12,6 +12,7 @@ import com.tangem.blockchainsdk.utils.toBlockchain
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.models.yield.supply.YieldSupplyStatus
import com.tangem.domain.utils.convertToSdkAmount
import com.tangem.domain.walletmanager.WalletManagersFacade
import com.tangem.domain.yield.supply.YieldSupplyTransactionRepository
@ -56,7 +57,7 @@ internal class DefaultYieldSupplyTransactionRepository(
return buildEnterTransactions(
walletManager = walletManager,
cryptoCurrencyStatus = cryptoCurrencyStatus,
existingYieldContractAddress = existingYieldContractAddress,
existingYieldAddress = existingYieldContractAddress,
calculatedYieldContractAddress = calculatedYieldContractAddress,
maxNetworkFee = maxNetworkFee,
)
@ -109,21 +110,23 @@ internal class DefaultYieldSupplyTransactionRepository(
}
@Suppress("LongParameterList")
private fun buildEnterTransactions(
private suspend fun buildEnterTransactions(
walletManager: WalletManager,
cryptoCurrencyStatus: CryptoCurrencyStatus,
existingYieldContractAddress: String?,
existingYieldAddress: String?,
calculatedYieldContractAddress: String,
maxNetworkFee: Amount,
): MutableList<TransactionData.Uncompiled> {
val enterTransactions = mutableListOf<TransactionData.Uncompiled>()
val cryptoCurrency = cryptoCurrencyStatus.currency as CryptoCurrency.Token
val yieldSupplyStatus = cryptoCurrencyStatus.value.yieldSupplyStatus
val yieldSupplyStatus = getYieldTokenStatus(walletManager, cryptoCurrency)
val amount = BigDecimal.ZERO.convertToSdkAmount(cryptoCurrencyStatus)
val amount = getEnterAmount(cryptoCurrency, yieldSupplyStatus)
val emptyContractAddress = existingYieldAddress == null || existingYieldAddress == EthereumUtils.ZERO_ADDRESS
when {
existingYieldContractAddress == null || existingYieldContractAddress == EthereumUtils.ZERO_ADDRESS -> {
yieldSupplyStatus == null || emptyContractAddress -> {
enterTransactions.add(
createDeployTransaction(
walletManager = walletManager,
@ -133,7 +136,6 @@ internal class DefaultYieldSupplyTransactionRepository(
),
)
}
yieldSupplyStatus == null -> error("Yield token status is null")
!yieldSupplyStatus.isInitialized -> enterTransactions.add(
createInitTokenTransaction(
walletManager = walletManager,
@ -211,6 +213,28 @@ internal class DefaultYieldSupplyTransactionRepository(
}.onFailure(Timber::e).getOrNull()
}
private suspend fun getYieldTokenStatus(
walletManager: WalletManager,
cryptoCurrency: CryptoCurrency.Token,
): YieldSupplyStatus? = withContext(dispatchers.io) {
runCatching {
val sdkSupplyStatus = walletManager.getYieldSupplyStatus(cryptoCurrency.contractAddress)
val isAllowedToSpend = walletManager.isAllowedToSpend(
Token(
symbol = cryptoCurrency.symbol,
contractAddress = cryptoCurrency.contractAddress,
decimals = cryptoCurrency.decimals,
),
)
YieldSupplyStatus(
isActive = sdkSupplyStatus?.isActive == true,
isInitialized = sdkSupplyStatus?.isInitialized == true,
isAllowedToSpend = isAllowedToSpend,
)
}.onFailure(Timber::e).getOrNull()
}
private fun createDeployTransaction(
walletManager: WalletManager,
cryptoCurrency: CryptoCurrency.Token,
@ -356,4 +380,20 @@ internal class DefaultYieldSupplyTransactionRepository(
else -> error("Data extras not supported for $blockchain")
}
}
private fun getEnterAmount(cryptoCurrency: CryptoCurrency.Token, yieldSupplyStatus: YieldSupplyStatus?) = Amount(
currencySymbol = cryptoCurrency.symbol,
value = BigDecimal.ZERO,
decimals = cryptoCurrency.decimals,
type = AmountType.TokenYieldSupply(
token = Token(
symbol = cryptoCurrency.symbol,
contractAddress = cryptoCurrency.contractAddress,
decimals = cryptoCurrency.decimals,
),
isActive = yieldSupplyStatus?.isActive ?: false,
isInitialized = yieldSupplyStatus?.isInitialized ?: false,
isAllowedToSpend = yieldSupplyStatus?.isAllowedToSpend ?: false,
),
)
}

View file

@ -12,7 +12,6 @@ import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.network.Network
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.models.yield.supply.YieldSupplyStatus
import com.tangem.domain.utils.convertToSdkAmount
import com.tangem.domain.walletmanager.WalletManagersFacade
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
@ -69,10 +68,10 @@ class DefaultYieldSupplyTransactionRepositoryTest {
@Test
fun `createEnterTransactions returns deploy-approve-enter transactions`() = runTest {
coEvery { walletManager.getYieldContract() } returns EthereumUtils.ZERO_ADDRESS
coEvery { walletManager.getYieldModuleAddress() } returns EthereumUtils.ZERO_ADDRESS
coEvery { walletManager.getYieldSupplyStatus(any()) } returns null
coEvery { walletManager.isAllowedToSpend(any()) } returns false
coEvery { walletManager.calculateYieldContract() } returns yieldContractAddress
coEvery { walletManager.calculateYieldModuleAddress() } returns yieldContractAddress
val result = repository.createEnterTransactions(
userWalletId = userWalletId,
@ -119,8 +118,8 @@ class DefaultYieldSupplyTransactionRepositoryTest {
@Test
fun `createEnterTransactions returns init-approve-enter transactions`() = runTest {
coEvery { walletManager.getYieldContract() } returns yieldContractAddress
coEvery { walletManager.calculateYieldContract() } returns yieldContractAddress
coEvery { walletManager.getYieldModuleAddress() } returns yieldContractAddress
coEvery { walletManager.calculateYieldModuleAddress() } returns yieldContractAddress
coEvery { walletManager.isAllowedToSpend(any()) } returns false
coEvery { walletManager.getYieldSupplyStatus(any()) } returns SDKYieldSupplyStatus(
isActive = false,
@ -172,8 +171,8 @@ class DefaultYieldSupplyTransactionRepositoryTest {
@Test
fun `createEnterTransactions returns reactivate-approve-enter transactions`() = runTest {
coEvery { walletManager.getYieldContract() } returns yieldContractAddress
coEvery { walletManager.calculateYieldContract() } returns yieldContractAddress
coEvery { walletManager.getYieldModuleAddress() } returns yieldContractAddress
coEvery { walletManager.calculateYieldModuleAddress() } returns yieldContractAddress
coEvery { walletManager.isAllowedToSpend(any()) } returns false
coEvery { walletManager.getYieldSupplyStatus(any()) } returns SDKYieldSupplyStatus(
isActive = false,
@ -225,8 +224,8 @@ class DefaultYieldSupplyTransactionRepositoryTest {
@Test
fun `createEnterTransactions returns reactivate-enter transactions`() = runTest {
coEvery { walletManager.getYieldContract() } returns yieldContractAddress
coEvery { walletManager.calculateYieldContract() } returns yieldContractAddress
coEvery { walletManager.getYieldModuleAddress() } returns yieldContractAddress
coEvery { walletManager.calculateYieldModuleAddress() } returns yieldContractAddress
coEvery { walletManager.getYieldSupplyStatus(any()) } returns SDKYieldSupplyStatus(
isActive = false,
isInitialized = true,
@ -266,8 +265,8 @@ class DefaultYieldSupplyTransactionRepositoryTest {
@Test
fun `createEnterTransactions returns enter transactions`() = runTest {
coEvery { walletManager.getYieldContract() } returns yieldContractAddress
coEvery { walletManager.calculateYieldContract() } returns yieldContractAddress
coEvery { walletManager.getYieldModuleAddress() } returns yieldContractAddress
coEvery { walletManager.calculateYieldModuleAddress() } returns yieldContractAddress
coEvery { walletManager.getYieldSupplyStatus(any()) } returns SDKYieldSupplyStatus(
isActive = true,
isInitialized = true,
@ -299,9 +298,7 @@ class DefaultYieldSupplyTransactionRepositoryTest {
val expectedCallData =
YieldSupplyContractCallDataProviderFactory.getExitCallData(mockedContractAddress)
val yieldSupplyStatus = mockk<YieldSupplyStatus>(relaxed = true)
val result = repository.createExitTransaction(userWalletId, cryptoCurrency, yieldSupplyStatus, null)
val result = repository.createExitTransaction(userWalletId, cryptoCurrencyStatus, null)
Truth.assertThat(result).isNotNull()
Truth.assertThat(result.extras).isInstanceOf(EthereumTransactionExtras::class.java)