Updated on 2026-08-14

This commit is contained in:
Tangem 2026-03-12 12:33:04 +04:00
parent 07f94d3a95
commit a2ec212c2e
18 changed files with 156 additions and 307 deletions

View file

@ -17,6 +17,7 @@ dependencies {
implementation(projects.core.ui)
/** Domain */
implementation(projects.domain.account.status)
implementation(projects.domain.models)
implementation(projects.domain.yieldSupply.models)
implementation(projects.domain.transaction.models)

View file

@ -2,13 +2,15 @@ package com.tangem.domain.yield.supply.usecase
import arrow.core.Either
import arrow.core.Either.Companion.catch
import arrow.core.getOrElse
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.transaction.Fee
import com.tangem.domain.account.status.utils.CryptoCurrencyOperations.getCoin
import com.tangem.domain.account.supplier.SingleAccountListSupplier
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.quote.QuoteStatus
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.quotes.QuotesRepository
import com.tangem.domain.tokens.repository.CurrenciesRepository
import com.tangem.domain.transaction.FeeRepository
import com.tangem.domain.yield.supply.YieldSupplyConst.YIELD_SUPPLY_EVM_CONSTANT_GAS_LIMIT
import com.tangem.domain.yield.supply.fixFee
@ -22,7 +24,7 @@ import java.math.RoundingMode
class YieldSupplyGetCurrentFeeUseCase(
private val feeRepository: FeeRepository,
private val quotesRepository: QuotesRepository,
private val currenciesRepository: CurrenciesRepository,
private val singleAccountListSupplier: SingleAccountListSupplier,
) {
suspend operator fun invoke(
@ -34,11 +36,13 @@ class YieldSupplyGetCurrentFeeUseCase(
val fiatRate = cryptoCurrencyStatus.value.fiatRate ?: error("Fiat rate is missing")
require(fiatRate > BigDecimal.ZERO) { "Fiat rate for token must be > 0" }
val nativeCryptoCurrency = currenciesRepository.getNetworkCoin(
userWalletId = userWalletId,
networkId = cryptoCurrencyStatus.currency.network.id,
derivationPath = cryptoCurrencyStatus.currency.network.derivationPath,
)
val accountStatusList = singleAccountListSupplier.getSyncOrNull(userWalletId = userWalletId)
?: error("Account status list is missing: $userWalletId")
val nativeCryptoCurrency = accountStatusList.getCoin(cryptoCurrencyStatus.currency)
.getOrElse {
error("Unable to find coin for network ID: ${cryptoCurrencyStatus.currency.network.id}")
}
val quotes =
quotesRepository.getMultiQuoteSyncOrNull(setOfNotNull(nativeCryptoCurrency.id.rawCurrencyId))

View file

@ -2,13 +2,15 @@ package com.tangem.domain.yield.supply.usecase
import arrow.core.Either
import arrow.core.Either.Companion.catch
import arrow.core.getOrElse
import com.tangem.domain.account.status.utils.CryptoCurrencyOperations.getCoin
import com.tangem.domain.account.supplier.SingleAccountListSupplier
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.currency.yieldSupplyKey
import com.tangem.domain.models.quote.QuoteStatus
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.quotes.QuotesRepository
import com.tangem.domain.tokens.repository.CurrenciesRepository
import com.tangem.domain.yield.supply.YieldSupplyRepository
import com.tangem.domain.yield.supply.models.YieldSupplyMaxFee
import java.math.BigDecimal
@ -28,7 +30,7 @@ import java.math.RoundingMode
class YieldSupplyGetMaxFeeUseCase(
private val yieldSupplyRepository: YieldSupplyRepository,
private val quotesRepository: QuotesRepository,
private val currenciesRepository: CurrenciesRepository,
private val singleAccountListSupplier: SingleAccountListSupplier,
) {
suspend operator fun invoke(
@ -41,11 +43,13 @@ class YieldSupplyGetMaxFeeUseCase(
val fiatRate = cryptoCurrencyStatus.value.fiatRate ?: error("Fiat rate is missing")
require(fiatRate > BigDecimal.ZERO) { "Fiat rate for token must be > 0" }
val nativeCryptoCurrency = currenciesRepository.getNetworkCoin(
userWalletId = userWalletId,
networkId = cryptoCurrencyStatus.currency.network.id,
derivationPath = cryptoCurrencyStatus.currency.network.derivationPath,
)
val accountStatusList = singleAccountListSupplier.getSyncOrNull(userWalletId = userWalletId)
?: error("Account status list is missing: $userWalletId")
val nativeCryptoCurrency = accountStatusList.getCoin(cryptoCurrencyStatus.currency)
.getOrElse {
error("Unable to find coin for network ID: ${cryptoCurrencyStatus.currency.network.id}")
}
val quotes =
quotesRepository.getMultiQuoteSyncOrNull(setOfNotNull(nativeCryptoCurrency.id.rawCurrencyId))

View file

@ -2,11 +2,13 @@ package com.tangem.domain.yield.supply.usecase
import arrow.core.Either
import arrow.core.Either.Companion.catch
import arrow.core.getOrElse
import com.tangem.domain.account.status.utils.CryptoCurrencyOperations.getCoin
import com.tangem.domain.account.supplier.SingleAccountListSupplier
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.quote.QuoteStatus
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.quotes.QuotesRepository
import com.tangem.domain.tokens.repository.CurrenciesRepository
import com.tangem.domain.transaction.FeeRepository
import com.tangem.domain.yield.supply.YieldSupplyConst.YIELD_SUPPLY_EVM_CONSTANT_GAS_LIMIT
import com.tangem.domain.yield.supply.fixFee
@ -24,7 +26,7 @@ import java.math.RoundingMode
class YieldSupplyMinAmountUseCase(
private val feeRepository: FeeRepository,
private val quotesRepository: QuotesRepository,
private val currenciesRepository: CurrenciesRepository,
private val singleAccountListSupplier: SingleAccountListSupplier,
) {
suspend operator fun invoke(
@ -36,11 +38,13 @@ class YieldSupplyMinAmountUseCase(
val fiatRate = cryptoCurrencyStatus.value.fiatRate ?: error("Fiat rate is missing")
require(fiatRate > BigDecimal.ZERO) { "Fiat rate for token must be > 0" }
val nativeCryptoCurrency = currenciesRepository.getNetworkCoin(
userWalletId = userWalletId,
networkId = cryptoCurrencyStatus.currency.network.id,
derivationPath = cryptoCurrencyStatus.currency.network.derivationPath,
)
val accountStatusList = singleAccountListSupplier.getSyncOrNull(userWalletId = userWalletId)
?: error("Account status list is missing: $userWalletId")
val nativeCryptoCurrency = accountStatusList.getCoin(cryptoCurrencyStatus.currency)
.getOrElse {
error("Unable to find coin for network ID: ${cryptoCurrencyStatus.currency.network.id}")
}
val quotes =
quotesRepository.getMultiQuoteSyncOrNull(setOfNotNull(nativeCryptoCurrency.id.rawCurrencyId))

View file

@ -4,6 +4,8 @@ import com.google.common.truth.Truth
import com.tangem.blockchain.common.Amount
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.transaction.Fee
import com.tangem.domain.account.models.AccountList
import com.tangem.domain.account.supplier.SingleAccountListSupplier
import com.tangem.domain.models.StatusSource
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.currency.CryptoCurrencyStatus
@ -13,7 +15,6 @@ import com.tangem.domain.models.quote.QuoteStatus
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.quotes.QuotesRepository
import com.tangem.domain.tokens.repository.CurrenciesRepository
import com.tangem.domain.transaction.FeeRepository
import com.tangem.domain.yield.supply.usecase.YieldSupplyMinAmountUseCase
import io.mockk.coEvery
@ -29,12 +30,12 @@ class YieldSupplyMinAmountUseCaseTest {
private val feeRepository: FeeRepository = mockk(relaxed = true)
private val quotesRepository: QuotesRepository = mockk(relaxed = true)
private val currenciesRepository: CurrenciesRepository = mockk(relaxed = true)
private val singleAccountListSupplier: SingleAccountListSupplier = mockk(relaxed = true)
private val useCase = YieldSupplyMinAmountUseCase(
feeRepository = feeRepository,
quotesRepository = quotesRepository,
currenciesRepository = currenciesRepository,
singleAccountListSupplier = singleAccountListSupplier,
)
@Test
@ -67,12 +68,11 @@ class YieldSupplyMinAmountUseCaseTest {
coEvery { feeRepository.getEthereumFeeWithoutGas(userWallet.walletId, token) } returns fee
coEvery {
currenciesRepository.getNetworkCoin(
userWalletId = userWallet.walletId,
networkId = token.network.id,
derivationPath = token.network.derivationPath,
)
} returns nativeCoin
singleAccountListSupplier.getSyncOrNull(userWalletId = userWallet.walletId)
} returns AccountList.empty(
userWalletId = userWallet.walletId,
cryptoCurrencies = listOf(nativeCoin, token),
)
val nativeFiatRate = BigDecimal("0.20353756561552608")
coEvery {
@ -147,12 +147,11 @@ class YieldSupplyMinAmountUseCaseTest {
coEvery { feeRepository.getEthereumFeeWithoutGas(userWallet.walletId, token) } returns fee
coEvery {
currenciesRepository.getNetworkCoin(
userWalletId = userWallet.walletId,
networkId = token.network.id,
derivationPath = token.network.derivationPath,
)
} returns nativeCoin
singleAccountListSupplier.getSyncOrNull(userWalletId = userWallet.walletId)
} returns AccountList.empty(
userWalletId = userWallet.walletId,
cryptoCurrencies = listOf(nativeCoin, token),
)
coEvery {
quotesRepository.getMultiQuoteSyncOrNull(setOf(nativeCoin.id.rawCurrencyId!!))

View file

@ -4,6 +4,8 @@ import arrow.core.Either
import com.google.common.truth.Truth.assertThat
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.transaction.Fee
import com.tangem.domain.account.models.AccountList
import com.tangem.domain.account.supplier.SingleAccountListSupplier
import com.tangem.domain.models.StatusSource
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.currency.CryptoCurrencyStatus
@ -12,7 +14,6 @@ import com.tangem.domain.models.network.NetworkAddress
import com.tangem.domain.models.quote.QuoteStatus
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.quotes.QuotesRepository
import com.tangem.domain.tokens.repository.CurrenciesRepository
import com.tangem.domain.transaction.FeeRepository
import com.tangem.domain.utils.convertToSdkAmount
import io.mockk.coEvery
@ -30,7 +31,7 @@ class YieldSupplyGetCurrentFeeUseCaseTest {
private val feeRepository: FeeRepository = mockk()
private val quotesRepository: QuotesRepository = mockk()
private val currenciesRepository: CurrenciesRepository = mockk()
private val singleAccountListSupplier: SingleAccountListSupplier = mockk()
private lateinit var useCase: YieldSupplyGetCurrentFeeUseCase
@ -41,7 +42,7 @@ class YieldSupplyGetCurrentFeeUseCaseTest {
useCase = YieldSupplyGetCurrentFeeUseCase(
feeRepository = feeRepository,
quotesRepository = quotesRepository,
currenciesRepository = currenciesRepository,
singleAccountListSupplier = singleAccountListSupplier,
)
}
@ -65,12 +66,11 @@ class YieldSupplyGetCurrentFeeUseCaseTest {
coEvery { feeRepository.getEthereumFeeWithoutGas(userWalletId, token) } returns feeWithoutGas
coEvery {
currenciesRepository.getNetworkCoin(
userWalletId = userWalletId,
networkId = token.network.id,
derivationPath = token.network.derivationPath,
)
} returns nativeCoin
singleAccountListSupplier.getSyncOrNull(userWalletId = userWalletId)
} returns AccountList.empty(
userWalletId = userWalletId,
cryptoCurrencies = listOf(nativeCoin, token),
)
coEvery {
quotesRepository.getMultiQuoteSyncOrNull(setOf(nativeCoin.id.rawCurrencyId!!))
} returns setOf(
@ -117,12 +117,11 @@ class YieldSupplyGetCurrentFeeUseCaseTest {
coEvery { feeRepository.getEthereumFeeWithoutGas(userWalletId, token) } returns feeWithoutGas
coEvery {
currenciesRepository.getNetworkCoin(
userWalletId = userWalletId,
networkId = token.network.id,
derivationPath = token.network.derivationPath,
)
} returns nativeCoin
singleAccountListSupplier.getSyncOrNull(userWalletId = userWalletId)
} returns AccountList.empty(
userWalletId = userWalletId,
cryptoCurrencies = listOf(nativeCoin, token),
)
coEvery {
quotesRepository.getMultiQuoteSyncOrNull(setOf(nativeCoin.id.rawCurrencyId!!))
} returns setOf(
@ -186,12 +185,11 @@ class YieldSupplyGetCurrentFeeUseCaseTest {
amount = BigDecimal.ZERO.convertToSdkAmount(cryptoStatus),
)
coEvery {
currenciesRepository.getNetworkCoin(
userWalletId = userWalletId,
networkId = token.network.id,
derivationPath = token.network.derivationPath,
)
} returns nativeCoin
singleAccountListSupplier.getSyncOrNull(userWalletId = userWalletId)
} returns AccountList.empty(
userWalletId = userWalletId,
cryptoCurrencies = listOf(nativeCoin, token),
)
coEvery { quotesRepository.getMultiQuoteSyncOrNull(setOf(nativeCoin.id.rawCurrencyId!!)) } returns null
val result = useCase(userWalletId, cryptoStatus)
@ -216,12 +214,11 @@ class YieldSupplyGetCurrentFeeUseCaseTest {
amount = BigDecimal.ZERO.convertToSdkAmount(cryptoStatus),
)
coEvery {
currenciesRepository.getNetworkCoin(
userWalletId = userWalletId,
networkId = token.network.id,
derivationPath = token.network.derivationPath,
)
} returns nativeCoin
singleAccountListSupplier.getSyncOrNull(userWalletId = userWalletId)
} returns AccountList.empty(
userWalletId = userWalletId,
cryptoCurrencies = listOf(nativeCoin, token),
)
coEvery { quotesRepository.getMultiQuoteSyncOrNull(setOf(nativeCoin.id.rawCurrencyId!!)) } returns emptySet()
val result = useCase(userWalletId, cryptoStatus)
@ -246,12 +243,11 @@ class YieldSupplyGetCurrentFeeUseCaseTest {
amount = BigDecimal.ZERO.convertToSdkAmount(cryptoStatus),
)
coEvery {
currenciesRepository.getNetworkCoin(
userWalletId = userWalletId,
networkId = token.network.id,
derivationPath = token.network.derivationPath,
)
} returns nativeCoin
singleAccountListSupplier.getSyncOrNull(userWalletId = userWalletId)
} returns AccountList.empty(
userWalletId = userWalletId,
cryptoCurrencies = listOf(nativeCoin, token),
)
coEvery {
quotesRepository.getMultiQuoteSyncOrNull(setOf(nativeCoin.id.rawCurrencyId!!))
} returns setOf(