diff --git a/app/src/main/java/com/tangem/tap/di/domain/YieldSupplyDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/YieldSupplyDomainModule.kt index ea0ad78e44..4e7acbe2eb 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/YieldSupplyDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/YieldSupplyDomainModule.kt @@ -169,8 +169,8 @@ internal object YieldSupplyDomainModule { yieldSupplyRepository: YieldSupplyRepository, quotesRepository: QuotesRepository, currenciesRepository: CurrenciesRepository, - ): YieldSupplyGetMaxFeeUseCase { - return YieldSupplyGetMaxFeeUseCase( + ): YieldSupplyGetTokenMaxFeeUseCase { + return YieldSupplyGetTokenMaxFeeUseCase( yieldSupplyRepository = yieldSupplyRepository, quotesRepository = quotesRepository, currenciesRepository = currenciesRepository, diff --git a/domain/yield-supply/models/src/main/java/com/tangem/domain/yield/supply/models/YieldSupplyMaxFee.kt b/domain/yield-supply/models/src/main/java/com/tangem/domain/yield/supply/models/YieldSupplyMaxFee.kt new file mode 100644 index 0000000000..160d52d47b --- /dev/null +++ b/domain/yield-supply/models/src/main/java/com/tangem/domain/yield/supply/models/YieldSupplyMaxFee.kt @@ -0,0 +1,9 @@ +package com.tangem.domain.yield.supply.models + +import java.math.BigDecimal + +data class YieldSupplyMaxFee( + val nativeMaxFee: BigDecimal, + val tokenMaxFee: BigDecimal, + val fiatMaxFee: BigDecimal, +) \ No newline at end of file diff --git a/domain/yield-supply/src/main/java/com/tangem/domain/yield/supply/usecase/YieldSupplyGetMaxFeeUseCase.kt b/domain/yield-supply/src/main/java/com/tangem/domain/yield/supply/usecase/YieldSupplyGetTokenMaxFeeUseCase.kt similarity index 81% rename from domain/yield-supply/src/main/java/com/tangem/domain/yield/supply/usecase/YieldSupplyGetMaxFeeUseCase.kt rename to domain/yield-supply/src/main/java/com/tangem/domain/yield/supply/usecase/YieldSupplyGetTokenMaxFeeUseCase.kt index 60a316b9f7..ca6f2af240 100644 --- a/domain/yield-supply/src/main/java/com/tangem/domain/yield/supply/usecase/YieldSupplyGetMaxFeeUseCase.kt +++ b/domain/yield-supply/src/main/java/com/tangem/domain/yield/supply/usecase/YieldSupplyGetTokenMaxFeeUseCase.kt @@ -10,21 +10,22 @@ import com.tangem.domain.models.wallet.UserWallet 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 import java.math.RoundingMode /** * Calculates the max allowed network fee for a Yield Supply transaction. * - * Result is a Pair where: - * - first: fee in native coin units (maxFeeNative) - * - second: the same fee converted to token units using the fiat-rate ratio - * (nativeFiatRate / tokenFiatRate). + * Returns [Either] of [YieldSupplyMaxFee] with: + * - nativeMaxFee: fee in native coin units + * - tokenMaxFee: fee converted to token units using the native/token rate ratio + * - tokenFiatMaxFee: fee value in fiat * * Uses YieldMarketToken.maxFeeNative and the same conversion logic as * [YieldSupplyGetCurrentFeeUseCase]. */ -class YieldSupplyGetMaxFeeUseCase( +class YieldSupplyGetTokenMaxFeeUseCase( private val yieldSupplyRepository: YieldSupplyRepository, private val quotesRepository: QuotesRepository, private val currenciesRepository: CurrenciesRepository, @@ -33,7 +34,7 @@ class YieldSupplyGetMaxFeeUseCase( suspend operator fun invoke( userWallet: UserWallet, cryptoCurrencyStatus: CryptoCurrencyStatus, - ): Either> = catch { + ): Either = catch { val token = cryptoCurrencyStatus.currency as? CryptoCurrency.Token ?: error("CryptoCurrency must be token for max fee calculation") @@ -60,6 +61,7 @@ class YieldSupplyGetMaxFeeUseCase( .firstOrNull { it.yieldSupplyKey == token.yieldSupplyKey() } val marketToken = cachedMarketToken ?: yieldSupplyRepository.getTokenStatus(token) val maxFeeNative = marketToken.maxFeeNative + val maxFeeToken = maxFeeNative.multiply(nativeFiatRate) val rateRatio = nativeFiatRate.divide( fiatRate, @@ -69,6 +71,10 @@ class YieldSupplyGetMaxFeeUseCase( val tokenValue = rateRatio.multiply(maxFeeNative) - maxFeeNative to tokenValue.stripTrailingZeros() + YieldSupplyMaxFee( + nativeMaxFee = maxFeeNative, + tokenMaxFee = maxFeeToken, + fiatMaxFee = tokenValue.stripTrailingZeros(), + ) } } \ No newline at end of file diff --git a/features/yield-supply/api/src/main/java/com/tangem/features/yield/supply/api/analytics/YieldSupplyAnalytics.kt b/features/yield-supply/api/src/main/java/com/tangem/features/yield/supply/api/analytics/YieldSupplyAnalytics.kt index 32c5975417..942e3a3d8a 100644 --- a/features/yield-supply/api/src/main/java/com/tangem/features/yield/supply/api/analytics/YieldSupplyAnalytics.kt +++ b/features/yield-supply/api/src/main/java/com/tangem/features/yield/supply/api/analytics/YieldSupplyAnalytics.kt @@ -99,8 +99,15 @@ sealed class YieldSupplyAnalytics( ), ) - data object FundsEarned : YieldSupplyAnalytics( + data class FundsEarned( + val token: String, + val blockchain: String, + ) : YieldSupplyAnalytics( event = "Funds Earned", + params = mapOf( + TOKEN_PARAM to token, + BLOCKCHAIN to blockchain, + ), ) data class FundsWithdrawn( diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/model/YieldSupplyActiveModel.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/model/YieldSupplyActiveModel.kt index bfb21a8ec9..e5cae54445 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/model/YieldSupplyActiveModel.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/model/YieldSupplyActiveModel.kt @@ -21,7 +21,7 @@ import com.tangem.domain.yield.supply.usecase.YieldSupplyGetProtocolBalanceUseCa import com.tangem.domain.yield.supply.usecase.YieldSupplyGetTokenStatusUseCase import com.tangem.domain.yield.supply.usecase.YieldSupplyMinAmountUseCase import com.tangem.domain.yield.supply.usecase.YieldSupplyGetCurrentFeeUseCase -import com.tangem.domain.yield.supply.usecase.YieldSupplyGetMaxFeeUseCase +import com.tangem.domain.yield.supply.usecase.YieldSupplyGetTokenMaxFeeUseCase import com.tangem.features.yield.supply.api.analytics.YieldSupplyAnalytics import com.tangem.features.yield.supply.impl.R import com.tangem.features.yield.supply.impl.subcomponents.active.YieldSupplyActiveComponent @@ -50,7 +50,7 @@ internal class YieldSupplyActiveModel @Inject constructor( private val yieldSupplyGetTokenStatusUseCase: YieldSupplyGetTokenStatusUseCase, private val yieldSupplyMinAmountUseCase: YieldSupplyMinAmountUseCase, private val yieldSupplyGetCurrentFeeUseCase: YieldSupplyGetCurrentFeeUseCase, - private val yieldSupplyGetMaxFeeUseCase: YieldSupplyGetMaxFeeUseCase, + private val yieldSupplyGetTokenMaxFeeUseCase: YieldSupplyGetTokenMaxFeeUseCase, private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase, ) : Model() { @@ -237,7 +237,7 @@ internal class YieldSupplyActiveModel @Inject constructor( cryptoCurrencyStatus = cryptoStatus, ).getOrNull() - val maxFee = yieldSupplyGetMaxFeeUseCase( + val maxFee = yieldSupplyGetTokenMaxFeeUseCase( userWallet = params.userWallet, cryptoCurrencyStatus = cryptoStatus, ).getOrNull() @@ -248,7 +248,7 @@ internal class YieldSupplyActiveModel @Inject constructor( cryptoCurrencyStatus = cryptoStatus, appCurrency = appCurrency, feeValue = currentFee, - maxNetworkFee = maxFee.second, + maxNetworkFee = maxFee, analyticsHandler = analyticsHandler, ), ) diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/model/transformers/YieldSupplyActiveFeeContentTransformer.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/model/transformers/YieldSupplyActiveFeeContentTransformer.kt index cc7f66e762..dbabb4a9f5 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/model/transformers/YieldSupplyActiveFeeContentTransformer.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/model/transformers/YieldSupplyActiveFeeContentTransformer.kt @@ -10,6 +10,7 @@ import com.tangem.core.ui.format.bigdecimal.format import com.tangem.core.ui.extensions.TextReference import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.models.currency.CryptoCurrencyStatus +import com.tangem.domain.yield.supply.models.YieldSupplyMaxFee import com.tangem.features.yield.supply.api.analytics.YieldSupplyAnalytics import com.tangem.features.yield.supply.impl.R import com.tangem.features.yield.supply.impl.subcomponents.active.entity.YieldSupplyActiveContentUM @@ -23,7 +24,7 @@ internal class YieldSupplyActiveFeeContentTransformer( private val cryptoCurrencyStatus: CryptoCurrencyStatus, private val appCurrency: AppCurrency, private val feeValue: BigDecimal, - private val maxNetworkFee: BigDecimal, + private val maxNetworkFee: YieldSupplyMaxFee, private val analyticsHandler: AnalyticsEventHandler, ) : Transformer { @@ -35,9 +36,12 @@ internal class YieldSupplyActiveFeeContentTransformer( val tokenFiatFee = tokenFiatRate?.let(feeValue::multiply) val tokenFiatFeeValueText = tokenFiatFee.format { fiat(appCurrency.code, appCurrency.symbol) } - val maxFeeCryptoValueText = maxNetworkFee.format { crypto(cryptoCurrency) } - val maxFiatFee = tokenFiatRate?.let { rate -> maxNetworkFee.multiply(rate) } - val maxFiatFeeValueText = maxFiatFee.format { fiat(appCurrency.code, appCurrency.symbol) } + val maxFeeCryptoValueText = maxNetworkFee.tokenMaxFee.format { crypto(cryptoCurrency) } + val maxFiatFeeValueText = maxNetworkFee.fiatMaxFee.format { fiat( + appCurrency.code, + appCurrency + .symbol, + ) } val feeNoteValue: TextReference = resourceReference( id = R.string.yield_module_fee_policy_sheet_fee_note, @@ -49,7 +53,7 @@ internal class YieldSupplyActiveFeeContentTransformer( ), ) - val isHighFee = feeValue > maxNetworkFee + val isHighFee = feeValue > maxNetworkFee.tokenMaxFee if (isHighFee) { analyticsHandler.send( diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/startearning/model/YieldSupplyStartEarningModel.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/startearning/model/YieldSupplyStartEarningModel.kt index c9dc6d5b65..59b294d623 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/startearning/model/YieldSupplyStartEarningModel.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/startearning/model/YieldSupplyStartEarningModel.kt @@ -62,7 +62,7 @@ internal class YieldSupplyStartEarningModel @Inject constructor( private val yieldSupplyAlertFactory: YieldSupplyAlertFactory, private val yieldSupplyActivateUseCase: YieldSupplyActivateUseCase, private val yieldSupplyMinAmountUseCase: YieldSupplyMinAmountUseCase, - private val yieldSupplyGetMaxFeeUseCase: YieldSupplyGetMaxFeeUseCase, + private val yieldSupplyGetTokenMaxFeeUseCase: YieldSupplyGetTokenMaxFeeUseCase, private val yieldSupplyRepository: YieldSupplyRepository, ) : Model(), YieldSupplyNotificationsComponent.ModelCallback { @@ -130,10 +130,6 @@ internal class YieldSupplyStartEarningModel @Inject constructor( } } - private suspend fun getMaxFeePair(): Pair? { - return yieldSupplyGetMaxFeeUseCase(userWallet, cryptoCurrencyStatus).getOrNull() - } - private suspend fun onLoadFee() { if (cryptoCurrencyStatus.value is CryptoCurrencyStatus.Loading || uiState.value.isTransactionSending) return @@ -141,15 +137,12 @@ internal class YieldSupplyStartEarningModel @Inject constructor( it.copy(yieldSupplyFeeUM = YieldSupplyFeeUM.Loading) } - val maxFeePair = getMaxFeePair() ?: return - - val maxFee = maxFeePair.first - val maxFeeFiat = maxFeePair.second + val maxFee = yieldSupplyGetTokenMaxFeeUseCase(userWallet, cryptoCurrencyStatus).getOrNull() ?: return val transactionListData = yieldSupplyStartEarningUseCase( userWalletId = userWallet.walletId, cryptoCurrencyStatus = cryptoCurrencyStatus, - maxNetworkFee = maxFee, + maxNetworkFee = maxFee.nativeMaxFee, ).getOrNull() if (transactionListData == null) { @@ -194,7 +187,6 @@ internal class YieldSupplyStartEarningModel @Inject constructor( updatedTransactionList = updatedTransactionList, feeValue = feeSum, maxNetworkFee = maxFee, - maxNetworkFeeFiat = maxFeeFiat, minAmount = minAmount, ), ) @@ -255,7 +247,10 @@ internal class YieldSupplyStartEarningModel @Inject constructor( token = cryptoCurrency.symbol, feeType = AnalyticsParam.FeeType.Normal, ) - analytics.send(YieldSupplyAnalytics.FundsEarned) + analytics.send(YieldSupplyAnalytics.FundsEarned( + blockchain = cryptoCurrency.network.name, + token = cryptoCurrency.symbol, + )) yieldSupplyFeeUM.transactionDataList.forEach { analytics.send( Basic.TransactionSent( diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/startearning/model/transformers/YieldSupplyStartEarningFeeContentTransformer.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/startearning/model/transformers/YieldSupplyStartEarningFeeContentTransformer.kt index 189ffa8a23..19696a8a93 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/startearning/model/transformers/YieldSupplyStartEarningFeeContentTransformer.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/startearning/model/transformers/YieldSupplyStartEarningFeeContentTransformer.kt @@ -9,6 +9,7 @@ import com.tangem.core.ui.format.bigdecimal.fiat import com.tangem.core.ui.format.bigdecimal.format import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.models.currency.CryptoCurrencyStatus +import com.tangem.domain.yield.supply.models.YieldSupplyMaxFee import com.tangem.features.yield.supply.impl.R import com.tangem.features.yield.supply.impl.common.entity.YieldSupplyActionUM import com.tangem.features.yield.supply.impl.common.entity.YieldSupplyFeeUM @@ -24,8 +25,7 @@ internal class YieldSupplyStartEarningFeeContentTransformer( private val appCurrency: AppCurrency, private val updatedTransactionList: List, private val feeValue: BigDecimal, - private val maxNetworkFee: BigDecimal, - private val maxNetworkFeeFiat: BigDecimal, + private val maxNetworkFee: YieldSupplyMaxFee, private val minAmount: BigDecimal, ) : Transformer { override fun transform(prevState: YieldSupplyActionUM): YieldSupplyActionUM { @@ -40,11 +40,10 @@ internal class YieldSupplyStartEarningFeeContentTransformer( feeFiat?.divide(rate, cryptoCurrency.decimals, RoundingMode.HALF_UP) } val tokenCryptoFeeValueText = tokenCryptoFee.format { crypto(cryptoCurrency) } - val tokenFiatFee = feeFiat // same fiat amount - val tokenFiatFeeValueText = tokenFiatFee.format { fiat(appCurrency.code, appCurrency.symbol) } + val tokenFiatFeeValueText = feeFiat.format { fiat(appCurrency.code, appCurrency.symbol) } - val maxFeeCryptoValueText = maxNetworkFee.format { crypto(cryptoCurrency) } - val maxFiatFeeValueText = maxNetworkFeeFiat.format { fiat(appCurrency.code, appCurrency.symbol) } + val maxFeeCryptoValueText = maxNetworkFee.tokenMaxFee.format { crypto(cryptoCurrency) } + val maxFiatFeeValueText = maxNetworkFee.fiatMaxFee.format { fiat(appCurrency.code, appCurrency.symbol) } val minAmountCryptoText = minAmount.format { crypto(cryptoCurrency) } val minAmountFiat = tokenFiatRate?.let(minAmount::multiply)