Updated on 2026-08-14
This commit is contained in:
parent
8564f21d01
commit
7740d6f453
18 changed files with 167 additions and 50 deletions
|
|
@ -291,7 +291,6 @@ internal object TransactionDomainModule {
|
|||
@Singleton
|
||||
fun provideGetFeeForGaslessUseCase(
|
||||
walletManagersFacade: WalletManagersFacade,
|
||||
demoConfig: DemoConfig,
|
||||
gaslessTransactionRepository: GaslessTransactionRepository,
|
||||
currenciesRepository: CurrenciesRepository,
|
||||
getFeeUseCase: GetFeeUseCase,
|
||||
|
|
@ -299,7 +298,7 @@ internal object TransactionDomainModule {
|
|||
): GetFeeForGaslessUseCase {
|
||||
return GetFeeForGaslessUseCase(
|
||||
walletManagersFacade = walletManagersFacade,
|
||||
demoConfig = demoConfig,
|
||||
demoConfig = DemoConfig,
|
||||
gaslessTransactionRepository = gaslessTransactionRepository,
|
||||
currenciesRepository = currenciesRepository,
|
||||
getMultiCryptoCurrencyStatusUseCase = getMultiCryptoCurrencyStatusUseCase,
|
||||
|
|
@ -311,7 +310,6 @@ internal object TransactionDomainModule {
|
|||
@Singleton
|
||||
fun provideGetFeeForTokenUseCase(
|
||||
walletManagersFacade: WalletManagersFacade,
|
||||
demoConfig: DemoConfig,
|
||||
gaslessTransactionRepository: GaslessTransactionRepository,
|
||||
currenciesRepository: CurrenciesRepository,
|
||||
getMultiCryptoCurrencyStatusUseCase: GetMultiCryptoCurrencyStatusUseCase,
|
||||
|
|
@ -319,7 +317,7 @@ internal object TransactionDomainModule {
|
|||
return GetFeeForTokenUseCase(
|
||||
gaslessTransactionRepository = gaslessTransactionRepository,
|
||||
walletManagersFacade = walletManagersFacade,
|
||||
demoConfig = demoConfig,
|
||||
demoConfig = DemoConfig,
|
||||
currenciesRepository = currenciesRepository,
|
||||
getMultiCryptoCurrencyStatusUseCase = getMultiCryptoCurrencyStatusUseCase,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -25,9 +25,9 @@ class MockedGaslessTransactionRepository(
|
|||
val usdcPolygon = responseCryptoCurrenciesFactory.createToken(
|
||||
blockchain = Blockchain.Polygon,
|
||||
sdkToken = Token(
|
||||
contractAddress = "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
|
||||
name = "USD Coin",
|
||||
symbol = "USDC",
|
||||
contractAddress = "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
||||
name = "Tether",
|
||||
symbol = "USDT",
|
||||
decimals = 6,
|
||||
),
|
||||
network = network,
|
||||
|
|
|
|||
|
|
@ -114,7 +114,9 @@ internal class TokenFeeCalculator(
|
|||
.toBigInteger()
|
||||
|
||||
val feeInTokenCurrency = coinPriceInTokenInBigDecimal.multiply(
|
||||
feeInNativeCurrency.toBigDecimal(),
|
||||
feeInNativeCurrency
|
||||
.toBigDecimal()
|
||||
.movePointLeft(nativeCurrencyStatus.currency.decimals),
|
||||
)
|
||||
|
||||
val tokenBalance = tokenForPayFeeStatus.value.amount ?: BigDecimal.ZERO
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
package com.tangem.features.send.v2.api.entity
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.tangem.blockchain.common.Amount
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.transaction.Fee
|
||||
import com.tangem.blockchain.common.transaction.TransactionFee
|
||||
import com.tangem.core.analytics.models.AnalyticsParam
|
||||
|
|
@ -44,7 +46,7 @@ sealed class FeeSelectorUM {
|
|||
is Custom,
|
||||
-> AnalyticsParam.FeeType.Custom
|
||||
is Fast -> AnalyticsParam.FeeType.Max
|
||||
is Market -> AnalyticsParam.FeeType.Normal
|
||||
is Market, is FeeItem.Loading -> AnalyticsParam.FeeType.Normal
|
||||
is Slow -> AnalyticsParam.FeeType.Min
|
||||
}
|
||||
}
|
||||
|
|
@ -84,6 +86,16 @@ sealed class FeeItem {
|
|||
return this::class == other::class
|
||||
}
|
||||
|
||||
fun isLoading(): Boolean {
|
||||
return this is Loading
|
||||
}
|
||||
|
||||
object Loading : FeeItem() {
|
||||
override val title: TextReference = resourceReference(R.string.common_fee_selector_option_market)
|
||||
override val iconRes: Int = R.drawable.ic_bird_24
|
||||
override val fee: Fee = Fee.Common(Amount(BigDecimal.ZERO, Blockchain.Unknown))
|
||||
}
|
||||
|
||||
data class Suggested(
|
||||
override val title: TextReference,
|
||||
override val fee: Fee,
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import com.tangem.features.send.v2.api.entity.FeeSelectorUM
|
|||
sealed class FeeSelectorParams {
|
||||
abstract val state: FeeSelectorUM
|
||||
abstract val userWalletId: UserWalletId
|
||||
abstract val onLoadFeeExtended: (suspend () -> Either<GetFeeError, TransactionFeeExtended>)?
|
||||
abstract val onLoadFeeExtended: (suspend (CryptoCurrencyStatus?) -> Either<GetFeeError, TransactionFeeExtended>)?
|
||||
abstract val onLoadFee: suspend () -> Either<GetFeeError, TransactionFee>
|
||||
abstract val cryptoCurrencyStatus: CryptoCurrencyStatus
|
||||
abstract val feeCryptoCurrencyStatus: CryptoCurrencyStatus
|
||||
|
|
@ -27,7 +27,9 @@ sealed class FeeSelectorParams {
|
|||
data class FeeSelectorBlockParams(
|
||||
override val state: FeeSelectorUM,
|
||||
override val userWalletId: UserWalletId,
|
||||
override val onLoadFeeExtended: (suspend () -> Either<GetFeeError, TransactionFeeExtended>)? = null,
|
||||
override val onLoadFeeExtended: (
|
||||
suspend (CryptoCurrencyStatus?) -> Either<GetFeeError, TransactionFeeExtended>
|
||||
)? = null,
|
||||
override val onLoadFee: suspend () -> Either<GetFeeError, TransactionFee>,
|
||||
override val cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
override val feeCryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
|
|
@ -40,7 +42,9 @@ sealed class FeeSelectorParams {
|
|||
data class FeeSelectorDetailsParams(
|
||||
override val state: FeeSelectorUM,
|
||||
override val userWalletId: UserWalletId,
|
||||
override val onLoadFeeExtended: (suspend () -> Either<GetFeeError, TransactionFeeExtended>)? = null,
|
||||
override val onLoadFeeExtended: (
|
||||
suspend (CryptoCurrencyStatus?) -> Either<GetFeeError, TransactionFeeExtended>
|
||||
)? = null,
|
||||
override val onLoadFee: suspend () -> Either<GetFeeError, TransactionFee>,
|
||||
override val cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
override val feeCryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ internal class DefaultFeeSelectorBlockComponent @AssistedInject constructor(
|
|||
params = FeeSelectorParams.FeeSelectorDetailsParams(
|
||||
state = model.uiState.value,
|
||||
onLoadFee = params.onLoadFee,
|
||||
onLoadFeeExtended = params.onLoadFeeExtended,
|
||||
feeCryptoCurrencyStatus = params.feeCryptoCurrencyStatus,
|
||||
cryptoCurrencyStatus = params.cryptoCurrencyStatus,
|
||||
callback = model,
|
||||
|
|
|
|||
|
|
@ -29,10 +29,6 @@ class FeeExtendedSelectorModel @Inject constructor(
|
|||
|
||||
private val params = paramsContainer.require<FeeSelectorComponentParams>()
|
||||
private var appCurrency: AppCurrency = AppCurrency.Default
|
||||
private val tokenConverter = SelectedTokenItemConverter(
|
||||
appCurrencyProvider = Provider { appCurrency },
|
||||
onTokenClick = { router.push(FeeSelectorRoute.ChooseToken) },
|
||||
)
|
||||
|
||||
init {
|
||||
initAppCurrency()
|
||||
|
|
@ -44,19 +40,13 @@ class FeeExtendedSelectorModel @Inject constructor(
|
|||
init {
|
||||
params.state
|
||||
.filterIsInstance<FeeSelectorUM.Content>()
|
||||
.onEach(::onParentStateUpdated)
|
||||
.onEach { state -> uiState.value = convertState(state) }
|
||||
.launchIn(modelScope)
|
||||
}
|
||||
|
||||
private fun getInitialState(): FeeExtendedSelectorUM {
|
||||
val parentContentState = params.state.value as FeeSelectorUM.Content
|
||||
|
||||
return FeeExtendedSelectorUM(
|
||||
parent = parentContentState,
|
||||
token = tokenConverter.convert(parentContentState.feeExtraInfo.feeCryptoCurrencyStatus),
|
||||
fee = parentContentState.selectedFeeItem,
|
||||
onFeeClick = { router.push(FeeSelectorRoute.ChooseSpeed) },
|
||||
)
|
||||
return convertState(parentContentState)
|
||||
}
|
||||
|
||||
private fun initAppCurrency() {
|
||||
|
|
@ -65,13 +55,18 @@ class FeeExtendedSelectorModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun onParentStateUpdated(state: FeeSelectorUM.Content) {
|
||||
uiState.update { current ->
|
||||
current.copy(
|
||||
parent = state,
|
||||
token = tokenConverter.convert(state.feeExtraInfo.feeCryptoCurrencyStatus),
|
||||
fee = state.selectedFeeItem,
|
||||
)
|
||||
}
|
||||
private fun convertState(state: FeeSelectorUM.Content): FeeExtendedSelectorUM {
|
||||
val tokenConverter = SelectedTokenItemConverter(
|
||||
appCurrencyProvider = Provider { appCurrency },
|
||||
onTokenClick = { router.push(FeeSelectorRoute.ChooseToken) },
|
||||
isTokenSelectionAvailable = state.feeExtraInfo.availableFeeCurrencies.orEmpty().size > 1,
|
||||
)
|
||||
|
||||
return FeeExtendedSelectorUM(
|
||||
parent = state,
|
||||
token = tokenConverter.convert(state.feeExtraInfo.feeCryptoCurrencyStatus),
|
||||
fee = state.selectedFeeItem,
|
||||
onFeeClick = { router.push(FeeSelectorRoute.ChooseSpeed) },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -16,6 +16,7 @@ import com.tangem.utils.converter.Converter
|
|||
internal class SelectedTokenItemConverter(
|
||||
private val appCurrencyProvider: Provider<AppCurrency>,
|
||||
private val onTokenClick: () -> Unit,
|
||||
private val isTokenSelectionAvailable: Boolean,
|
||||
) : Converter<CryptoCurrencyStatus, TokenItemState> {
|
||||
|
||||
override fun convert(value: CryptoCurrencyStatus): TokenItemState {
|
||||
|
|
@ -24,9 +25,14 @@ internal class SelectedTokenItemConverter(
|
|||
}
|
||||
|
||||
val appCurrency = appCurrencyProvider()
|
||||
|
||||
val tokenItemConverter = TokenItemStateConverter(
|
||||
appCurrency = appCurrencyProvider(),
|
||||
onItemClick = { _, _ -> onTokenClick() },
|
||||
onItemClick = if (isTokenSelectionAvailable) {
|
||||
{ _, _ -> onTokenClick() }
|
||||
} else {
|
||||
null
|
||||
},
|
||||
)
|
||||
|
||||
val state = tokenItemConverter.convert(value)
|
||||
|
|
@ -38,10 +44,14 @@ internal class SelectedTokenItemConverter(
|
|||
}
|
||||
|
||||
state.copy(
|
||||
fiatAmountState = TokenItemState.FiatAmountState.Icon(
|
||||
iconRes = R.drawable.ic_select_18_24,
|
||||
tint = IconTint.Informative,
|
||||
),
|
||||
fiatAmountState = if (isTokenSelectionAvailable) {
|
||||
TokenItemState.FiatAmountState.Icon(
|
||||
iconRes = R.drawable.ic_select_18_24,
|
||||
tint = IconTint.Informative,
|
||||
)
|
||||
} else {
|
||||
TokenItemState.FiatAmountState.Empty
|
||||
},
|
||||
subtitleState = TokenItemState.SubtitleState.TextContent(
|
||||
value = resourceReference(
|
||||
R.string.common_balance,
|
||||
|
|
@ -50,7 +60,6 @@ internal class SelectedTokenItemConverter(
|
|||
isAvailable = false,
|
||||
),
|
||||
subtitle2State = null,
|
||||
|
||||
)
|
||||
}
|
||||
else -> state
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import com.tangem.core.ui.components.currency.icon.CurrencyIconState
|
|||
import com.tangem.core.ui.components.icons.IconTint
|
||||
import com.tangem.core.ui.components.token.TokenItem
|
||||
import com.tangem.core.ui.components.token.state.TokenItemState
|
||||
import com.tangem.core.ui.extensions.conditional
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.format.bigdecimal.crypto
|
||||
import com.tangem.core.ui.format.bigdecimal.fee
|
||||
|
|
@ -61,12 +62,15 @@ fun FeeExtendedSelectorContent(state: FeeExtendedSelectorUM, modifier: Modifier
|
|||
|
||||
val feeFiatRateUM = state.parent.feeFiatRateUM
|
||||
val fee = state.fee.fee
|
||||
val isChooseSpeedAvailable = state.parent.feeItems.size > 1
|
||||
|
||||
RegularFeeItemContent(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(TangemTheme.dimens.radius14))
|
||||
.clickable(onClick = state.onFeeClick)
|
||||
.conditional(isChooseSpeedAvailable) {
|
||||
clickable(onClick = state.onFeeClick)
|
||||
}
|
||||
.background(
|
||||
TangemTheme.colors.background.action,
|
||||
RoundedCornerShape(TangemTheme.dimens.radius14),
|
||||
|
|
@ -93,7 +97,8 @@ fun FeeExtendedSelectorContent(state: FeeExtendedSelectorUM, modifier: Modifier
|
|||
null
|
||||
},
|
||||
ellipsizeOffset = fee.amount.currencySymbol.length,
|
||||
showSelectorIcon = true,
|
||||
showSelectorIcon = isChooseSpeedAvailable,
|
||||
isLoading = state.fee.isLoading(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ import com.tangem.blockchain.common.transaction.TransactionFee
|
|||
import com.tangem.common.ui.amountScreen.utils.getFiatReference
|
||||
import com.tangem.core.ui.components.SpacerH8
|
||||
import com.tangem.core.ui.components.SpacerWMax
|
||||
import com.tangem.core.ui.components.TextShimmer
|
||||
import com.tangem.core.ui.components.atoms.text.EllipsisText
|
||||
import com.tangem.core.ui.components.atoms.text.TextEllipsis
|
||||
import com.tangem.core.ui.components.inputrow.InputRowEnter
|
||||
|
|
@ -325,6 +326,7 @@ internal fun RegularFeeItemContent(
|
|||
postDot: TextReference? = null,
|
||||
ellipsizeOffset: Int? = null,
|
||||
showSelectorIcon: Boolean = false,
|
||||
isLoading: Boolean = false,
|
||||
) {
|
||||
Column(modifier = modifier) {
|
||||
Row(
|
||||
|
|
@ -349,6 +351,7 @@ internal fun RegularFeeItemContent(
|
|||
preDot = preDot,
|
||||
postDot = postDot,
|
||||
ellipsizeOffset = ellipsizeOffset,
|
||||
isLoading = isLoading,
|
||||
)
|
||||
|
||||
if (showSelectorIcon) {
|
||||
|
|
@ -371,6 +374,7 @@ private fun FeeDescription(
|
|||
preDot: TextReference? = null,
|
||||
postDot: TextReference? = null,
|
||||
ellipsizeOffset: Int? = null,
|
||||
isLoading: Boolean = false,
|
||||
) {
|
||||
Column(modifier = modifier, verticalArrangement = Arrangement.spacedBy(2.dp)) {
|
||||
Text(
|
||||
|
|
@ -379,8 +383,12 @@ private fun FeeDescription(
|
|||
style = TangemTheme.typography.subtitle2,
|
||||
modifier = Modifier.testTag(SendSelectNetworkFeeBottomSheetTestTags.REGULAR_ITEM_TITLE),
|
||||
)
|
||||
if (preDot != null) {
|
||||
FeeValueContent(preDot = preDot, postDot = postDot, ellipsizeOffset = ellipsizeOffset)
|
||||
when {
|
||||
isLoading -> TextShimmer(
|
||||
modifier = Modifier.width(122.dp),
|
||||
style = TangemTheme.typography.caption1,
|
||||
)
|
||||
preDot != null -> FeeValueContent(preDot = preDot, postDot = postDot, ellipsizeOffset = ellipsizeOffset)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import kotlinx.collections.immutable.persistentListOf
|
|||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.filterIsInstance
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
|
|
@ -47,7 +48,8 @@ internal class FeeTokenSelectorModel @Inject constructor(
|
|||
initAppCurrency()
|
||||
|
||||
params.state
|
||||
.onEach { uiState.value = stateFromParent(it as FeeSelectorUM.Content) }
|
||||
.filterIsInstance<FeeSelectorUM.Content>()
|
||||
.onEach { state -> uiState.value = stateFromParent(state) }
|
||||
.launchIn(modelScope)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@ internal class FeeSelectorAlertFactory @Inject constructor(
|
|||
is FeeItem.Slow -> newTransactionFee.minimum
|
||||
is FeeItem.Market -> newTransactionFee.normal
|
||||
is FeeItem.Fast -> newTransactionFee.priority
|
||||
FeeItem.Loading -> newTransactionFee.normal
|
||||
is FeeItem.Custom -> return
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import com.tangem.blockchain.common.transaction.TransactionFee
|
|||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.tokens.GetSingleCryptoCurrencyStatusUseCase
|
||||
import com.tangem.domain.transaction.error.GetFeeError
|
||||
|
|
@ -31,6 +32,7 @@ import com.tangem.utils.transformer.update
|
|||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
|
|
@ -56,6 +58,7 @@ internal class FeeSelectorLogic @AssistedInject constructor(
|
|||
) : FeeSelectorIntents {
|
||||
|
||||
private var appCurrency: AppCurrency = AppCurrency.Default
|
||||
private var selectedToken: CryptoCurrencyStatus? = null
|
||||
val uiState = MutableStateFlow<FeeSelectorUM>(params.state)
|
||||
|
||||
init {
|
||||
|
|
@ -112,9 +115,19 @@ internal class FeeSelectorLogic @AssistedInject constructor(
|
|||
}
|
||||
|
||||
override fun onTokenSelected(status: CryptoCurrencyStatus) {
|
||||
if (status.currency !is CryptoCurrency.Token ||
|
||||
status.currency.id == params.feeCryptoCurrencyStatus.currency.id) {
|
||||
selectedToken = null
|
||||
loadFee()
|
||||
return
|
||||
}
|
||||
uiState.update(FeeSelectorTokenSelectedTransformer(status))
|
||||
|
||||
uiState.update { state ->
|
||||
if (state is FeeSelectorUM.Content) {
|
||||
state.copy(
|
||||
selectedFeeItem = FeeItem.Loading,
|
||||
feeItems = persistentListOf(FeeItem.Loading),
|
||||
feeExtraInfo = state.feeExtraInfo.copy(
|
||||
feeCryptoCurrencyStatus = status,
|
||||
),
|
||||
|
|
@ -123,6 +136,14 @@ internal class FeeSelectorLogic @AssistedInject constructor(
|
|||
state
|
||||
}
|
||||
}
|
||||
|
||||
if (status.currency is CryptoCurrency.Token) {
|
||||
selectedToken = status
|
||||
} else {
|
||||
selectedToken = null
|
||||
}
|
||||
|
||||
loadFee()
|
||||
}
|
||||
|
||||
override fun onCustomFeeValueChange(index: Int, value: String) {
|
||||
|
|
@ -219,7 +240,7 @@ internal class FeeSelectorLogic @AssistedInject constructor(
|
|||
private suspend fun callLoadFee(): Either<GetFeeError, LoadedFeeResult> {
|
||||
val extended = params.onLoadFeeExtended
|
||||
return if (extended != null && sendFeatureToggles.isGaslessTransactionsEnabled) {
|
||||
extended().fold(
|
||||
extended(selectedToken).fold(
|
||||
ifLeft = { error ->
|
||||
if (error is GetFeeError.GaslessError) {
|
||||
params.onLoadFee().map { LoadedFeeResult.Basic(it) }
|
||||
|
|
|
|||
|
|
@ -43,7 +43,8 @@ internal class FeeSelectorLoadedTransformer(
|
|||
)
|
||||
|
||||
val selectedFee = when (prevState) {
|
||||
is FeeSelectorUM.Content -> feeItems.first { it.isSameClass(prevState.selectedFeeItem) }
|
||||
is FeeSelectorUM.Content ->
|
||||
feeItems.firstOrNull { it.isSameClass(prevState.selectedFeeItem) } ?: FeeItem.Loading
|
||||
is FeeSelectorUM.Error,
|
||||
FeeSelectorUM.Loading,
|
||||
-> feeItems.find { it is FeeItem.Suggested } ?: feeItems.first { it is FeeItem.Market }
|
||||
|
|
@ -52,7 +53,7 @@ internal class FeeSelectorLoadedTransformer(
|
|||
val nonce = ((prevState as? FeeSelectorUM.Content)?.feeNonce as? FeeNonce.Nonce)?.nonce
|
||||
|
||||
return FeeSelectorUM.Content(
|
||||
isPrimaryButtonEnabled = true,
|
||||
isPrimaryButtonEnabled = selectedFee !is FeeItem.Loading,
|
||||
fees = fees.transactionFee,
|
||||
feeItems = feeItems,
|
||||
selectedFeeItem = selectedFee,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
package com.tangem.features.send.v2.feeselector.model.transformers
|
||||
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.features.send.v2.api.entity.FeeItem
|
||||
import com.tangem.features.send.v2.api.entity.FeeSelectorUM
|
||||
import com.tangem.utils.transformer.Transformer
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
class FeeSelectorTokenSelectedTransformer(
|
||||
private val selectedToken: CryptoCurrencyStatus,
|
||||
) : Transformer<FeeSelectorUM> {
|
||||
|
||||
override fun transform(prevState: FeeSelectorUM): FeeSelectorUM {
|
||||
return if (prevState is FeeSelectorUM.Content) {
|
||||
prevState.copy(
|
||||
selectedFeeItem = FeeItem.Loading,
|
||||
feeItems = persistentListOf(FeeItem.Loading),
|
||||
feeExtraInfo = prevState.feeExtraInfo.copy(
|
||||
feeCryptoCurrencyStatus = selectedToken,
|
||||
),
|
||||
)
|
||||
} else {
|
||||
prevState
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -216,6 +216,7 @@ internal class DefaultSendComponent @AssistedInject constructor(
|
|||
callback = model,
|
||||
predefinedValues = model.predefinedValues,
|
||||
onLoadFee = model::loadFee,
|
||||
onLoadFeeExtended = model::loadFeeExtended,
|
||||
onSendTransaction = {
|
||||
innerRouter.replaceAll(CommonSendRoute.ConfirmSuccess)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import com.tangem.domain.models.account.Account
|
|||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.transaction.error.GetFeeError
|
||||
import com.tangem.domain.transaction.models.TransactionFeeExtended
|
||||
import com.tangem.features.send.v2.api.FeeSelectorBlockComponent
|
||||
import com.tangem.features.send.v2.api.SendNotificationsComponent
|
||||
import com.tangem.features.send.v2.api.SendNotificationsComponent.Params.NotificationData
|
||||
|
|
@ -86,6 +87,7 @@ internal class SendConfirmComponent(
|
|||
params = FeeSelectorParams.FeeSelectorBlockParams(
|
||||
state = model.uiState.value.feeSelectorUM,
|
||||
onLoadFee = params.onLoadFee,
|
||||
onLoadFeeExtended = params.onLoadFeeExtended,
|
||||
feeCryptoCurrencyStatus = params.feeCryptoCurrencyStatus,
|
||||
cryptoCurrencyStatus = params.cryptoCurrencyStatus,
|
||||
feeStateConfiguration = model.feeStateConfiguration,
|
||||
|
|
@ -164,6 +166,7 @@ internal class SendConfirmComponent(
|
|||
val isBalanceHidingFlow: StateFlow<Boolean>,
|
||||
val predefinedValues: PredefinedValues,
|
||||
val onLoadFee: suspend () -> Either<GetFeeError, TransactionFee>,
|
||||
val onLoadFeeExtended: suspend (CryptoCurrencyStatus?) -> Either<GetFeeError, TransactionFeeExtended>,
|
||||
val onSendTransaction: () -> Unit,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import androidx.compose.runtime.Stable
|
|||
import arrow.core.Either
|
||||
import arrow.core.getOrElse
|
||||
import arrow.core.left
|
||||
import com.tangem.blockchain.common.TransactionData
|
||||
import com.tangem.blockchain.common.transaction.TransactionFee
|
||||
import com.tangem.common.ui.amountScreen.models.AmountState
|
||||
import com.tangem.common.ui.navigationButtons.NavigationUM
|
||||
|
|
@ -37,8 +38,11 @@ import com.tangem.domain.tokens.GetFeePaidCryptoCurrencyStatusSyncUseCase
|
|||
import com.tangem.domain.tokens.GetSingleCryptoCurrencyStatusUseCase
|
||||
import com.tangem.domain.tokens.error.CurrencyStatusError
|
||||
import com.tangem.domain.transaction.error.GetFeeError
|
||||
import com.tangem.domain.transaction.models.TransactionFeeExtended
|
||||
import com.tangem.domain.transaction.usecase.CreateTransferTransactionUseCase
|
||||
import com.tangem.domain.transaction.usecase.GetFeeUseCase
|
||||
import com.tangem.domain.transaction.usecase.gasless.GetFeeForGaslessUseCase
|
||||
import com.tangem.domain.transaction.usecase.gasless.GetFeeForTokenUseCase
|
||||
import com.tangem.domain.utils.convertToSdkAmount
|
||||
import com.tangem.domain.wallets.models.GetUserWalletError
|
||||
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
||||
|
|
@ -95,6 +99,8 @@ internal class SendModel @Inject constructor(
|
|||
private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
|
||||
private val createTransferTransactionUseCase: CreateTransferTransactionUseCase,
|
||||
private val getFeeUseCase: GetFeeUseCase,
|
||||
private val getFeeForGaslessUseCase: GetFeeForGaslessUseCase,
|
||||
private val getFeeForTokenUseCase: GetFeeForTokenUseCase,
|
||||
private val getAccountCurrencyStatusUseCase: GetAccountCurrencyStatusUseCase,
|
||||
private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase,
|
||||
private val sendAmountUpdateTrigger: SendAmountUpdateTrigger,
|
||||
|
|
@ -245,10 +251,10 @@ internal class SendModel @Inject constructor(
|
|||
showAlertError()
|
||||
}
|
||||
|
||||
suspend fun loadFee(): Either<GetFeeError, TransactionFee> {
|
||||
suspend fun prepareTransferTransaction(): Either<Throwable, TransactionData> {
|
||||
val predefinedValues = predefinedValues
|
||||
val cryptoCurrencyStatus = cryptoCurrencyStatusFlow.value
|
||||
val transferTransaction = if (predefinedValues is PredefinedValues.Content.Deeplink) {
|
||||
return if (predefinedValues is PredefinedValues.Content.Deeplink) {
|
||||
val predefinedAmount = predefinedValues.amount.parseBigDecimalOrNull()
|
||||
createTransferTransactionUseCase(
|
||||
amount = predefinedAmount?.convertToSdkAmount(cryptoCurrencyStatus) ?: error("Invalid amount"),
|
||||
|
|
@ -271,9 +277,12 @@ internal class SendModel @Inject constructor(
|
|||
userWalletId = userWallet.walletId,
|
||||
network = cryptoCurrency.network,
|
||||
)
|
||||
}.getOrElse {
|
||||
return GetFeeError.DataError(it).left()
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun loadFee(): Either<GetFeeError, TransactionFee> {
|
||||
val transferTransaction = prepareTransferTransaction()
|
||||
.getOrElse { return GetFeeError.DataError(it).left() }
|
||||
|
||||
return getFeeUseCase(
|
||||
transactionData = transferTransaction,
|
||||
|
|
@ -282,6 +291,25 @@ internal class SendModel @Inject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
suspend fun loadFeeExtended(maybeToken: CryptoCurrencyStatus?): Either<GetFeeError, TransactionFeeExtended> {
|
||||
val transferTransaction = prepareTransferTransaction()
|
||||
.getOrElse { return GetFeeError.DataError(it).left() }
|
||||
|
||||
return if (maybeToken == null) {
|
||||
getFeeForGaslessUseCase(
|
||||
transactionData = transferTransaction,
|
||||
userWallet = userWallet,
|
||||
network = params.currency.network,
|
||||
)
|
||||
} else {
|
||||
getFeeForTokenUseCase(
|
||||
transactionData = transferTransaction,
|
||||
userWallet = userWallet,
|
||||
token = maybeToken.currency,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun showAlertError() {
|
||||
sendConfirmAlertFactory.getGenericErrorState(
|
||||
onFailedTxEmailClick = ::onFailedTxEmailClick,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue