Updated on 2026-08-14

This commit is contained in:
Tangem 2024-02-01 14:54:55 +03:00
commit ef41a1261c
11 changed files with 89 additions and 9 deletions

View file

@ -2,9 +2,11 @@ package com.tangem.tap.di.domain
import com.tangem.domain.card.repository.CardSdkConfigRepository
import com.tangem.domain.demo.IsDemoCardUseCase
import com.tangem.domain.transaction.FeeRepository
import com.tangem.domain.transaction.TransactionRepository
import com.tangem.domain.transaction.usecase.CreateTransactionUseCase
import com.tangem.domain.transaction.usecase.GetFeeUseCase
import com.tangem.domain.transaction.usecase.IsFeeApproximateUseCase
import com.tangem.domain.transaction.usecase.SendTransactionUseCase
import com.tangem.domain.walletmanager.WalletManagersFacade
import dagger.Module
@ -42,4 +44,10 @@ internal object TransactionDomainModule {
fun provideCreateTransactionUseCase(transactionRepository: TransactionRepository): CreateTransactionUseCase {
return CreateTransactionUseCase(transactionRepository)
}
@Provides
@ViewModelScoped
fun provideIsFeeApproximateUseCase(feeRepository: FeeRepository): IsFeeApproximateUseCase {
return IsFeeApproximateUseCase(feeRepository)
}
}

View file

@ -10,6 +10,7 @@ import java.util.Locale
object BigDecimalFormatter {
const val EMPTY_BALANCE_SIGN = ""
const val CAN_BE_LOWER_SIGN = "<"
private const val TEMP_CURRENCY_CODE = "USD"

View file

@ -0,0 +1,13 @@
package com.tangem.data.transaction
import com.tangem.blockchain.common.AmountType
import com.tangem.blockchain.common.Blockchain
import com.tangem.domain.tokens.model.Network
import com.tangem.domain.transaction.FeeRepository
internal class DefaultFeeRepository : FeeRepository {
override fun isFeeApproximate(networkId: Network.ID, amountType: AmountType): Boolean {
val blockchain = Blockchain.fromId(networkId.value)
return blockchain.isFeeApproximate(amountType)
}
}

View file

@ -1,6 +1,8 @@
package com.tangem.data.transaction.di
import com.tangem.data.transaction.DefaultFeeRepository
import com.tangem.data.transaction.DefaultTransactionRepository
import com.tangem.domain.transaction.FeeRepository
import com.tangem.domain.transaction.TransactionRepository
import com.tangem.domain.walletmanager.WalletManagersFacade
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
@ -25,4 +27,10 @@ internal object TransactionDataModule {
coroutineDispatcherProvider = coroutineDispatcherProvider,
)
}
@Provides
@Singleton
fun providesFeeRepository(): FeeRepository {
return DefaultFeeRepository()
}
}

View file

@ -0,0 +1,10 @@
package com.tangem.domain.transaction
import com.tangem.blockchain.common.AmountType
import com.tangem.domain.tokens.model.Network
interface FeeRepository {
/** Returns if fee is approximate for current [networkId] */
fun isFeeApproximate(networkId: Network.ID, amountType: AmountType): Boolean
}

View file

@ -0,0 +1,19 @@
package com.tangem.domain.transaction.usecase
import com.tangem.blockchain.common.AmountType
import com.tangem.domain.tokens.model.Network
import com.tangem.domain.transaction.FeeRepository
/**
* Use case to check if fee is approximate
*
* @param feeRepository [FeeRepository]
*/
class IsFeeApproximateUseCase(
private val feeRepository: FeeRepository,
) {
operator fun invoke(networkId: Network.ID, amountType: AmountType): Boolean {
return feeRepository.isFeeApproximate(networkId, amountType)
}
}

View file

@ -77,6 +77,7 @@ internal sealed class SendStates {
val receivedAmount: String,
val rate: BigDecimal?,
val appCurrency: AppCurrency,
val isFeeApproximate: Boolean,
val notifications: ImmutableList<SendFeeNotification>,
) : SendStates()

View file

@ -5,6 +5,7 @@ import com.tangem.blockchain.common.transaction.TransactionFee
import com.tangem.core.ui.utils.BigDecimalFormatter
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.transaction.usecase.IsFeeApproximateUseCase
import com.tangem.features.send.impl.presentation.state.SendStates
import com.tangem.features.send.impl.presentation.state.SendUiState
import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents
@ -24,6 +25,7 @@ internal class FeeStateFactory(
private val coinCryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
private val appCurrencyProvider: Provider<AppCurrency>,
private val isFeeApproximateUseCase: IsFeeApproximateUseCase,
) {
private val customFeeFieldConverter by lazy {
SendFeeCustomFieldConverter(
@ -66,6 +68,7 @@ internal class FeeStateFactory(
receivedAmountValue = receivedAmount,
receivedAmount = getFormattedValue(receivedAmount),
isSubtract = isSubtractAvailable && checkAutoSubtract(state, fee, balance),
isFeeApproximate = isFeeApproximate(fee),
),
)
}
@ -206,6 +209,14 @@ internal class FeeStateFactory(
}
}
private fun isFeeApproximate(fee: Fee): Boolean {
val cryptoCurrencyStatus = cryptoCurrencyStatusProvider()
return isFeeApproximateUseCase(
networkId = cryptoCurrencyStatus.currency.network.id,
amountType = fee.amount.type,
)
}
private fun getFormattedValue(value: BigDecimal): String {
val cryptoCurrency = cryptoCurrencyStatusProvider().currency
return BigDecimalFormatter.formatCryptoAmount(

View file

@ -26,6 +26,7 @@ internal class SendFeeStateConverter(
notifications = persistentListOf(),
rate = cryptoCurrencyStatus.value.fiatRate,
appCurrency = appCurrencyProvider(),
isFeeApproximate = false,
)
}
}

View file

@ -28,10 +28,12 @@ import com.tangem.core.ui.components.SpacerWMax
import com.tangem.core.ui.components.atoms.text.EllipsisText
import com.tangem.core.ui.components.atoms.text.TextEllipsis
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.combinedReference
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.utils.BigDecimalFormatter
import com.tangem.core.ui.utils.BigDecimalFormatter.CAN_BE_LOWER_SIGN
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.features.send.impl.R
import com.tangem.features.send.impl.presentation.state.SendStates
@ -79,7 +81,7 @@ internal fun SendSpeedSelector(
SendSpeedSelectorItem(
titleRes = R.string.common_fee_selector_option_slow,
iconRes = R.drawable.ic_tortoise_24,
amount = getCryptoReference(minimumAmount),
amount = getCryptoReference(minimumAmount, state.isFeeApproximate),
fiatAmount = getFiatReference(minimumAmount, state.rate, state.appCurrency),
symbolLength = minimumAmount.currencySymbol.length,
isSelected = isSelected == FeeType.SLOW,
@ -89,7 +91,7 @@ internal fun SendSpeedSelector(
SendSpeedSelectorItem(
titleRes = R.string.common_fee_selector_option_market,
iconRes = R.drawable.ic_bird_24,
amount = getCryptoReference(normalAmount),
amount = getCryptoReference(normalAmount, state.isFeeApproximate),
fiatAmount = getFiatReference(normalAmount, state.rate, state.appCurrency),
symbolLength = normalAmount.currencySymbol.length,
isSelected = isSelected == FeeType.MARKET,
@ -99,7 +101,7 @@ internal fun SendSpeedSelector(
SendSpeedSelectorItem(
titleRes = R.string.common_fee_selector_option_fast,
iconRes = R.drawable.ic_hare_24,
amount = getCryptoReference(priorityAmount),
amount = getCryptoReference(priorityAmount, state.isFeeApproximate),
fiatAmount = getFiatReference(priorityAmount, state.rate, state.appCurrency),
symbolLength = priorityAmount.currencySymbol.length,
isSelected = isSelected == FeeType.FAST,
@ -125,7 +127,7 @@ internal fun SendSpeedSelector(
titleRes = R.string.common_fee_selector_option_market,
iconRes = R.drawable.ic_bird_24,
isSelected = true,
amount = getCryptoReference(normalAmount),
amount = getCryptoReference(normalAmount, state.isFeeApproximate),
fiatAmount = getFiatReference(normalAmount, state.rate, state.appCurrency),
symbolLength = normalAmount.currencySymbol.length,
onSelect = { clickIntents.onFeeSelectorClick(FeeType.MARKET) },
@ -140,11 +142,14 @@ internal fun SendSpeedSelector(
}
// todo remove after refactoring [REDACTED_JIRA]
private fun getCryptoReference(amount: Amount) = stringReference(
BigDecimalFormatter.formatCryptoAmount(
cryptoAmount = amount.value,
cryptoCurrency = amount.currencySymbol,
decimals = amount.decimals,
private fun getCryptoReference(amount: Amount, isFeeApproximate: Boolean) = combinedReference(
if (isFeeApproximate) stringReference("$CAN_BE_LOWER_SIGN ") else TextReference.EMPTY,
stringReference(
BigDecimalFormatter.formatCryptoAmount(
cryptoAmount = amount.value,
cryptoCurrency = amount.currencySymbol,
decimals = amount.decimals,
),
),
)

View file

@ -24,6 +24,7 @@ import com.tangem.domain.tokens.utils.convertToAmount
import com.tangem.domain.transaction.error.GetFeeError
import com.tangem.domain.transaction.usecase.CreateTransactionUseCase
import com.tangem.domain.transaction.usecase.GetFeeUseCase
import com.tangem.domain.transaction.usecase.IsFeeApproximateUseCase
import com.tangem.domain.transaction.usecase.SendTransactionUseCase
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.domain.txhistory.usecase.GetExplorerTransactionUrlUseCase
@ -70,6 +71,7 @@ internal class SendViewModel @Inject constructor(
private val walletManagersFacade: WalletManagersFacade,
private val reduxStateHolder: ReduxStateHolder,
private val isAmountSubtractAvailableUseCase: IsAmountSubtractAvailableUseCase,
private val isFeeApproximateUseCase: IsFeeApproximateUseCase,
getExplorerTransactionUrlUseCase: GetExplorerTransactionUrlUseCase,
validateWalletMemoUseCase: ValidateWalletMemoUseCase,
getBalanceNotEnoughForFeeWarningUseCase: GetBalanceNotEnoughForFeeWarningUseCase,
@ -104,6 +106,7 @@ internal class SendViewModel @Inject constructor(
coinCryptoCurrencyStatusProvider = Provider { coinCryptoCurrencyStatus },
cryptoCurrencyStatusProvider = Provider { cryptoCurrencyStatus },
appCurrencyProvider = Provider(selectedAppCurrencyFlow::value),
isFeeApproximateUseCase = isFeeApproximateUseCase,
)
private val eventStateFactory = SendEventStateFactory(