Updated on 2026-08-14
This commit is contained in:
commit
714eb51ce5
34 changed files with 345 additions and 114 deletions
|
|
@ -4,12 +4,14 @@ import com.tangem.core.decompose.factory.ComponentFactory
|
|||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.tokens.model.details.NavigationAction
|
||||
|
||||
interface TokenDetailsComponent : ComposableContentComponent {
|
||||
|
||||
data class Params(
|
||||
val userWalletId: UserWalletId,
|
||||
val currency: CryptoCurrency,
|
||||
val navigationAction: NavigationAction? = null,
|
||||
)
|
||||
|
||||
interface Factory : ComponentFactory<Params, TokenDetailsComponent>
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import com.tangem.core.decompose.model.getOrCreateModel
|
|||
import com.tangem.core.ui.components.NavigationBar3ButtonsScrim
|
||||
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.details.NavigationAction
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.model.TokenDetailsModel
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.route.TokenDetailsBottomSheetConfig
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.ui.TokenDetailsScreen
|
||||
|
|
@ -76,6 +77,8 @@ internal class DefaultTokenDetailsComponent @AssistedInject constructor(
|
|||
params = YieldSupplyComponent.Params(
|
||||
userWalletId = params.userWalletId,
|
||||
cryptoCurrency = params.currency,
|
||||
handleNavigation = (params.navigationAction as? NavigationAction.YieldSupply)
|
||||
?.isActive,
|
||||
),
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ import com.tangem.domain.tokens.model.TokenActionsState
|
|||
import com.tangem.domain.tokens.model.analytics.*
|
||||
import com.tangem.domain.tokens.model.analytics.TokenScreenAnalyticsEvent.Companion.toReasonAnalyticsText
|
||||
import com.tangem.domain.tokens.model.analytics.TokenScreenAnalyticsEvent.DetailsScreenOpened.TokenBalance
|
||||
import com.tangem.domain.tokens.model.details.NavigationAction
|
||||
import com.tangem.domain.tokens.model.details.TokenAction
|
||||
import com.tangem.domain.transaction.error.AssociateAssetError
|
||||
import com.tangem.domain.transaction.error.IncompleteTransactionError
|
||||
|
|
@ -222,6 +223,7 @@ internal class TokenDetailsModel @Inject constructor(
|
|||
updateContent()
|
||||
handleBalanceHiding()
|
||||
checkForActionUpdates()
|
||||
handleNavigationParam()
|
||||
}
|
||||
|
||||
fun onResume() {
|
||||
|
|
@ -1246,6 +1248,12 @@ internal class TokenDetailsModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun handleNavigationParam() {
|
||||
if (params.navigationAction is NavigationAction.Staking) {
|
||||
openStaking()
|
||||
}
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val EXPRESS_STATUS_UPDATE_DELAY = 10_000L
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,9 +3,12 @@ package com.tangem.feature.wallet.child.wallet.model.intents
|
|||
import arrow.core.getOrElse
|
||||
import com.tangem.common.ui.expressStatus.ExpressStatusBottomSheetConfig
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.core.analytics.models.event.MainScreenAnalyticsEvent
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.domain.models.account.Account
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.staking.YieldBalance
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.models.wallet.isLocked
|
||||
|
|
@ -14,6 +17,7 @@ import com.tangem.domain.settings.ShouldShowMarketsTooltipUseCase
|
|||
import com.tangem.domain.tokens.GetCryptoCurrencyActionsUseCase
|
||||
import com.tangem.domain.tokens.GetSingleCryptoCurrencyStatusUseCase
|
||||
import com.tangem.domain.tokens.model.TokenActionsState
|
||||
import com.tangem.domain.tokens.model.details.NavigationAction
|
||||
import com.tangem.domain.txhistory.usecase.GetExplorerTransactionUrlUseCase
|
||||
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
||||
import com.tangem.feature.wallet.presentation.account.AccountDependencies
|
||||
|
|
@ -45,6 +49,8 @@ internal interface WalletContentClickIntents {
|
|||
|
||||
fun onTokenItemLongClick(userWalletId: UserWalletId, cryptoCurrencyStatus: CryptoCurrencyStatus)
|
||||
|
||||
fun onApyLabelClick(userWalletId: UserWalletId, currencyStatus: CryptoCurrencyStatus)
|
||||
|
||||
fun onAccountExpandClick(account: Account)
|
||||
|
||||
fun onAccountCollapseClick(account: Account)
|
||||
|
|
@ -154,6 +160,42 @@ internal class WalletContentClickIntentsImplementor @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override fun onApyLabelClick(userWalletId: UserWalletId, currencyStatus: CryptoCurrencyStatus) {
|
||||
val navigationAction = if (currencyStatus.currency is CryptoCurrency.Token) {
|
||||
NavigationAction.YieldSupply(currencyStatus.value.yieldSupplyStatus?.isActive == true)
|
||||
} else {
|
||||
NavigationAction.Staking
|
||||
}
|
||||
val event = when (navigationAction) {
|
||||
is NavigationAction.YieldSupply -> {
|
||||
MainScreenAnalyticsEvent.ApyClicked(
|
||||
token = currencyStatus.currency.symbol,
|
||||
blockchain = currencyStatus.currency.network.name,
|
||||
action = "Earning",
|
||||
state = if (currencyStatus.value.yieldSupplyStatus?.isActive == true) {
|
||||
"Enabled"
|
||||
} else {
|
||||
"Disabled"
|
||||
},
|
||||
)
|
||||
}
|
||||
is NavigationAction.Staking -> {
|
||||
MainScreenAnalyticsEvent.ApyClicked(
|
||||
token = currencyStatus.currency.symbol,
|
||||
blockchain = currencyStatus.currency.network.name,
|
||||
action = "Staking",
|
||||
state = if (currencyStatus.value.yieldBalance is YieldBalance.Data) {
|
||||
"Enabled"
|
||||
} else {
|
||||
"Disabled"
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
analyticsEventHandler.send(event)
|
||||
router.openTokenDetails(userWalletId, currencyStatus, navigationAction)
|
||||
}
|
||||
|
||||
override fun onAccountExpandClick(account: Account) {
|
||||
val userWalletId = stateHolder.getSelectedWalletId()
|
||||
accountDependencies.expandedAccountsHolder.expandAccount(userWalletId, account.accountId)
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import com.tangem.domain.models.wallet.UserWalletId
|
|||
import com.tangem.domain.pay.TangemPayDetailsConfig
|
||||
import com.tangem.domain.redux.ReduxStateHolder
|
||||
import com.tangem.domain.redux.StateDialog
|
||||
import com.tangem.domain.tokens.model.details.NavigationAction
|
||||
import com.tangem.domain.tokens.model.details.TokenAction
|
||||
import com.tangem.feature.wallet.navigation.WalletRoute
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletDialogConfig
|
||||
|
|
@ -66,13 +67,18 @@ internal class DefaultWalletRouter @Inject constructor(
|
|||
urlOpener.openUrl(url)
|
||||
}
|
||||
|
||||
override fun openTokenDetails(userWalletId: UserWalletId, currencyStatus: CryptoCurrencyStatus) {
|
||||
override fun openTokenDetails(
|
||||
userWalletId: UserWalletId,
|
||||
currencyStatus: CryptoCurrencyStatus,
|
||||
navigationAction: NavigationAction?,
|
||||
) {
|
||||
val networkAddress = currencyStatus.value.networkAddress
|
||||
if (networkAddress != null && networkAddress.defaultAddress.value.isNotEmpty()) {
|
||||
router.push(
|
||||
AppRoute.CurrencyDetails(
|
||||
userWalletId = userWalletId,
|
||||
currency = currencyStatus.currency,
|
||||
navigationAction = navigationAction,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import com.tangem.domain.models.scan.ScanResponse
|
|||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.pay.TangemPayDetailsConfig
|
||||
import com.tangem.domain.tokens.model.details.NavigationAction
|
||||
import com.tangem.domain.tokens.model.details.TokenAction
|
||||
import com.tangem.feature.wallet.navigation.WalletRoute
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletDialogConfig
|
||||
|
|
@ -42,7 +43,11 @@ internal interface InnerWalletRouter {
|
|||
fun openUrl(url: String)
|
||||
|
||||
/** Open token details screen */
|
||||
fun openTokenDetails(userWalletId: UserWalletId, currencyStatus: CryptoCurrencyStatus)
|
||||
fun openTokenDetails(
|
||||
userWalletId: UserWalletId,
|
||||
currencyStatus: CryptoCurrencyStatus,
|
||||
navigationAction: NavigationAction? = null,
|
||||
)
|
||||
|
||||
/** Open stories screen */
|
||||
fun openStoriesScreen()
|
||||
|
|
|
|||
|
|
@ -49,12 +49,17 @@ internal class TokenListStateConverter(
|
|||
clickIntents.onTokenItemLongClick(selectedWallet.walletId, currencyStatus)
|
||||
}
|
||||
|
||||
private val onApyLabelClick: (currencyStatus: CryptoCurrencyStatus) -> Unit = { currencyStatus ->
|
||||
clickIntents.onApyLabelClick(selectedWallet.walletId, currencyStatus)
|
||||
}
|
||||
|
||||
private fun tokenStatusConverter(accountId: AccountId? = null) = TokenItemStateConverter(
|
||||
appCurrency = appCurrency,
|
||||
yieldModuleApyMap = yieldModuleApyMap,
|
||||
stakingApyMap = stakingApyMap,
|
||||
onItemClick = { _, status -> onTokenClick(accountId, status) },
|
||||
onItemLongClick = { _, status -> onTokenLongClick(accountId, status) },
|
||||
onApyLabelClick = { status -> onApyLabelClick(status) },
|
||||
)
|
||||
|
||||
override fun convert(value: WalletTokensListState): WalletTokensListState {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ interface YieldSupplyComponent : ComposableContentComponent {
|
|||
data class Params(
|
||||
val userWalletId: UserWalletId,
|
||||
val cryptoCurrency: CryptoCurrency,
|
||||
val handleNavigation: Boolean? = null,
|
||||
)
|
||||
|
||||
interface Factory : ComponentFactory<Params, YieldSupplyComponent>
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ internal sealed class YieldSupplyFeeUM {
|
|||
data class Content(
|
||||
val transactionDataList: ImmutableList<TransactionData.Uncompiled>,
|
||||
val feeFiatValue: TextReference,
|
||||
// TODO move to FeePolicyUM
|
||||
val estimatedFiatValue: TextReference,
|
||||
val tokenFeeFiatValue: TextReference,
|
||||
val maxNetworkFeeFiatValue: TextReference,
|
||||
val minTopUpFiatValue: TextReference,
|
||||
|
|
|
|||
|
|
@ -149,6 +149,7 @@ private class YieldSupplyActionContentPreviewProvider : PreviewParameterProvider
|
|||
maxNetworkFeeFiatValue = stringReference("$8.50"),
|
||||
minTopUpFiatValue = stringReference("$50"),
|
||||
feeNoteValue = TextReference.EMPTY,
|
||||
estimatedFiatValue = TextReference.EMPTY,
|
||||
),
|
||||
isPrimaryButtonEnabled = false,
|
||||
isTransactionSending = false,
|
||||
|
|
|
|||
|
|
@ -91,6 +91,16 @@ internal class YieldSupplyModel @Inject constructor(
|
|||
|
||||
init {
|
||||
checkIfYieldSupplyIsAvailable()
|
||||
params.handleNavigation?.let { handle ->
|
||||
if (handle) {
|
||||
modelScope.launch {
|
||||
delay(timeMillis = 1000)
|
||||
bottomSheetNavigation.activate(Unit)
|
||||
}
|
||||
} else {
|
||||
onStartEarningClick()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkIfYieldSupplyIsAvailable() {
|
||||
|
|
@ -185,7 +195,10 @@ internal class YieldSupplyModel @Inject constructor(
|
|||
@Suppress("MaximumLineLength")
|
||||
private fun onCryptoCurrencyStatusUpdated(cryptoCurrencyStatus: CryptoCurrencyStatus) {
|
||||
val yieldSupplyStatus = cryptoCurrencyStatus.value.yieldSupplyStatus
|
||||
val tokenProtocolStatus = yieldSupplyRepository.getTokenProtocolStatus(cryptoCurrency)
|
||||
val tokenProtocolStatus = yieldSupplyRepository.getTokenProtocolStatus(
|
||||
userWallet.walletId,
|
||||
cryptoCurrency,
|
||||
)
|
||||
val isActive = yieldSupplyStatus?.isActive == true
|
||||
val isCryptoCurrencyStatusFromCache = cryptoCurrencyStatus.value.sources.networkSource != StatusSource.ACTUAL
|
||||
val processing = uiState.value is YieldSupplyUM.Processing
|
||||
|
|
@ -298,7 +311,11 @@ internal class YieldSupplyModel @Inject constructor(
|
|||
val address = cryptoCurrencyStatus.value.networkAddress?.defaultAddress?.value ?: return
|
||||
modelScope.launch(dispatchers.default) {
|
||||
if (cryptoCurrencyStatus.value.yieldSupplyStatus?.isActive == true) {
|
||||
yieldSupplyActivateUseCase(token, address).onRight {
|
||||
yieldSupplyActivateUseCase(
|
||||
userWalletId = userWallet.walletId,
|
||||
cryptoCurrency = token,
|
||||
address = address,
|
||||
).onRight {
|
||||
lastYieldSupplyStatus = cryptoCurrencyStatus.value.yieldSupplyStatus
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -248,7 +248,7 @@ internal class YieldSupplyActiveModel @Inject constructor(
|
|||
cryptoCurrencyStatus = cryptoStatus,
|
||||
appCurrency = appCurrency,
|
||||
feeValue = currentFee,
|
||||
maxNetworkFee = maxFee.second,
|
||||
maxNetworkFee = maxFee,
|
||||
analyticsHandler = analyticsHandler,
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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<YieldSupplyActiveContentUM> {
|
||||
|
||||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -255,6 +255,7 @@ internal class YieldSupplyApproveModel @Inject constructor(
|
|||
maxNetworkFeeFiatValue = TextReference.EMPTY,
|
||||
minTopUpFiatValue = TextReference.EMPTY,
|
||||
feeNoteValue = TextReference.EMPTY,
|
||||
estimatedFiatValue = TextReference.EMPTY,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ internal fun YieldSupplyFeePolicyContent(
|
|||
.padding(horizontal = 16.dp),
|
||||
) {
|
||||
val currentFee = when (yieldSupplyFeeUM) {
|
||||
is YieldSupplyFeeUM.Content -> yieldSupplyFeeUM.tokenFeeFiatValue
|
||||
is YieldSupplyFeeUM.Content -> yieldSupplyFeeUM.estimatedFiatValue
|
||||
YieldSupplyFeeUM.Error -> stringReference(StringsSigns.DASH_SIGN)
|
||||
YieldSupplyFeeUM.Loading -> null
|
||||
}
|
||||
|
|
@ -184,6 +184,7 @@ private fun YieldSupplyFeePolicyContent_Preview() {
|
|||
stringReference("2.46 USDT"),
|
||||
),
|
||||
),
|
||||
estimatedFiatValue = stringReference("$8.50"),
|
||||
),
|
||||
tokenSymbol = "USDT",
|
||||
modifier = Modifier.background(TangemTheme.colors.background.primary),
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ internal class YieldSupplyStartEarningModel @Inject constructor(
|
|||
private val yieldSupplyActivateUseCase: YieldSupplyActivateUseCase,
|
||||
private val yieldSupplyMinAmountUseCase: YieldSupplyMinAmountUseCase,
|
||||
private val yieldSupplyGetMaxFeeUseCase: YieldSupplyGetMaxFeeUseCase,
|
||||
private val yieldSupplyGetCurrentFeeUseCase: YieldSupplyGetCurrentFeeUseCase,
|
||||
private val yieldSupplyRepository: YieldSupplyRepository,
|
||||
) : Model(), YieldSupplyNotificationsComponent.ModelCallback {
|
||||
|
||||
|
|
@ -130,10 +131,6 @@ internal class YieldSupplyStartEarningModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private suspend fun getMaxFeePair(): Pair<BigDecimal, BigDecimal>? {
|
||||
return yieldSupplyGetMaxFeeUseCase(userWallet, cryptoCurrencyStatus).getOrNull()
|
||||
}
|
||||
|
||||
private suspend fun onLoadFee() {
|
||||
if (cryptoCurrencyStatus.value is CryptoCurrencyStatus.Loading || uiState.value.isTransactionSending) return
|
||||
|
||||
|
|
@ -141,15 +138,13 @@ internal class YieldSupplyStartEarningModel @Inject constructor(
|
|||
it.copy(yieldSupplyFeeUM = YieldSupplyFeeUM.Loading)
|
||||
}
|
||||
|
||||
val maxFeePair = getMaxFeePair() ?: return
|
||||
|
||||
val maxFee = maxFeePair.first
|
||||
val maxFeeFiat = maxFeePair.second
|
||||
val maxFee = yieldSupplyGetMaxFeeUseCase(userWallet, cryptoCurrencyStatus).getOrNull() ?: return
|
||||
val estimatedFee = yieldSupplyGetCurrentFeeUseCase(userWallet, cryptoCurrencyStatus).getOrNull() ?: return
|
||||
|
||||
val transactionListData = yieldSupplyStartEarningUseCase(
|
||||
userWalletId = userWallet.walletId,
|
||||
cryptoCurrencyStatus = cryptoCurrencyStatus,
|
||||
maxNetworkFee = maxFee,
|
||||
maxNetworkFee = maxFee.nativeMaxFee,
|
||||
).getOrNull()
|
||||
|
||||
if (transactionListData == null) {
|
||||
|
|
@ -194,7 +189,7 @@ internal class YieldSupplyStartEarningModel @Inject constructor(
|
|||
updatedTransactionList = updatedTransactionList,
|
||||
feeValue = feeSum,
|
||||
maxNetworkFee = maxFee,
|
||||
maxNetworkFeeFiat = maxFeeFiat,
|
||||
estimatedFeeValue = estimatedFee,
|
||||
minAmount = minAmount,
|
||||
),
|
||||
)
|
||||
|
|
@ -249,35 +244,52 @@ internal class YieldSupplyStartEarningModel @Inject constructor(
|
|||
)
|
||||
},
|
||||
ifRight = {
|
||||
yieldSupplyRepository.saveTokenProtocolStatus(cryptoCurrency, YieldSupplyEnterStatus.Enter)
|
||||
val event = AnalyticsParam.TxSentFrom.Earning(
|
||||
blockchain = cryptoCurrency.network.name,
|
||||
token = cryptoCurrency.symbol,
|
||||
feeType = AnalyticsParam.FeeType.Normal,
|
||||
)
|
||||
analytics.send(YieldSupplyAnalytics.FundsEarned)
|
||||
yieldSupplyFeeUM.transactionDataList.forEach {
|
||||
analytics.send(
|
||||
Basic.TransactionSent(
|
||||
sentFrom = event,
|
||||
memoType = Basic.TransactionSent.MemoType.Null,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
val address = cryptoCurrencyStatus.value.networkAddress?.defaultAddress?.value
|
||||
if (address != null) {
|
||||
yieldSupplyActivateUseCase(cryptoCurrency, address)
|
||||
}
|
||||
|
||||
modelScope.launch {
|
||||
params.callback.onTransactionSent()
|
||||
}
|
||||
onStartEarningTransactionSuccess(yieldSupplyFeeUM)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun onStartEarningTransactionSuccess(yieldSupplyFeeUM: YieldSupplyFeeUM.Content) {
|
||||
yieldSupplyRepository.saveTokenProtocolStatus(
|
||||
userWallet.walletId,
|
||||
cryptoCurrency,
|
||||
YieldSupplyEnterStatus.Enter,
|
||||
)
|
||||
val event = AnalyticsParam.TxSentFrom.Earning(
|
||||
blockchain = cryptoCurrency.network.name,
|
||||
token = cryptoCurrency.symbol,
|
||||
feeType = AnalyticsParam.FeeType.Normal,
|
||||
)
|
||||
analytics.send(
|
||||
YieldSupplyAnalytics.FundsEarned(
|
||||
blockchain = cryptoCurrency.network.name,
|
||||
token = cryptoCurrency.symbol,
|
||||
),
|
||||
)
|
||||
yieldSupplyFeeUM.transactionDataList.forEach {
|
||||
analytics.send(
|
||||
Basic.TransactionSent(
|
||||
sentFrom = event,
|
||||
memoType = Basic.TransactionSent.MemoType.Null,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
val address = cryptoCurrencyStatus.value.networkAddress?.defaultAddress?.value
|
||||
if (address != null) {
|
||||
yieldSupplyActivateUseCase(
|
||||
userWalletId = userWallet.walletId,
|
||||
cryptoCurrency = cryptoCurrency,
|
||||
address = address,
|
||||
)
|
||||
}
|
||||
|
||||
modelScope.launch {
|
||||
params.callback.onTransactionSent()
|
||||
}
|
||||
}
|
||||
|
||||
private fun subscribeOnCurrencyStatusUpdates() {
|
||||
modelScope.launch {
|
||||
getUserWalletUseCase(params.userWalletId).fold(
|
||||
|
|
|
|||
|
|
@ -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,8 @@ internal class YieldSupplyStartEarningFeeContentTransformer(
|
|||
private val appCurrency: AppCurrency,
|
||||
private val updatedTransactionList: List<TransactionData.Uncompiled>,
|
||||
private val feeValue: BigDecimal,
|
||||
private val maxNetworkFee: BigDecimal,
|
||||
private val maxNetworkFeeFiat: BigDecimal,
|
||||
private val estimatedFeeValue: BigDecimal,
|
||||
private val maxNetworkFee: YieldSupplyMaxFee,
|
||||
private val minAmount: BigDecimal,
|
||||
) : Transformer<YieldSupplyActionUM> {
|
||||
override fun transform(prevState: YieldSupplyActionUM): YieldSupplyActionUM {
|
||||
|
|
@ -36,15 +37,17 @@ internal class YieldSupplyStartEarningFeeContentTransformer(
|
|||
val feeFiat = feeFiatRate?.let(feeValue::multiply)
|
||||
val feeFiatValueText = feeFiat.format { fiat(appCurrency.code, appCurrency.symbol) }
|
||||
|
||||
val estimatedFeeFiat = estimatedFeeValue
|
||||
val estimatedFeeFiatValueText = estimatedFeeFiat.format { fiat(appCurrency.code, appCurrency.symbol) }
|
||||
|
||||
val tokenCryptoFee = tokenFiatRate?.let { rate ->
|
||||
feeFiat?.divide(rate, cryptoCurrency.decimals, RoundingMode.HALF_UP)
|
||||
estimatedFeeFiat.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 = estimatedFeeFiat.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)
|
||||
|
|
@ -80,6 +83,7 @@ internal class YieldSupplyStartEarningFeeContentTransformer(
|
|||
minTopUpFiatValue = stringReference(minAmountFiatText),
|
||||
feeNoteValue = feeNoteValue,
|
||||
minFeeNoteValue = minFeeNoteValue,
|
||||
estimatedFiatValue = stringReference(estimatedFeeFiatValueText),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -165,37 +165,45 @@ internal class YieldSupplyStopEarningModel @Inject constructor(
|
|||
)
|
||||
},
|
||||
ifRight = {
|
||||
yieldSupplyRepository.saveTokenProtocolStatus(cryptoCurrency, YieldSupplyEnterStatus.Exit)
|
||||
analytics.send(
|
||||
YieldSupplyAnalytics.FundsWithdrawn(
|
||||
token = cryptoCurrency.symbol,
|
||||
blockchain = cryptoCurrency.network.name,
|
||||
),
|
||||
)
|
||||
val event = AnalyticsParam.TxSentFrom.Earning(
|
||||
blockchain = cryptoCurrency.network.name,
|
||||
token = cryptoCurrency.symbol,
|
||||
feeType = AnalyticsParam.FeeType.Normal,
|
||||
)
|
||||
analytics.send(
|
||||
Basic.TransactionSent(
|
||||
sentFrom = event,
|
||||
memoType = Basic.TransactionSent.MemoType.Null,
|
||||
),
|
||||
)
|
||||
val address = cryptoCurrencyStatus.value.networkAddress?.defaultAddress?.value
|
||||
if (address != null) {
|
||||
yieldSupplyDeactivateUseCase(cryptoCurrency, address)
|
||||
}
|
||||
|
||||
modelScope.launch {
|
||||
params.callback.onTransactionSent()
|
||||
}
|
||||
onStopEarningTransactionSuccess()
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun onStopEarningTransactionSuccess() {
|
||||
yieldSupplyRepository.saveTokenProtocolStatus(
|
||||
userWallet.walletId,
|
||||
cryptoCurrency,
|
||||
YieldSupplyEnterStatus.Exit,
|
||||
)
|
||||
analytics.send(
|
||||
YieldSupplyAnalytics.FundsWithdrawn(
|
||||
token = cryptoCurrency.symbol,
|
||||
blockchain = cryptoCurrency.network.name,
|
||||
),
|
||||
)
|
||||
val event = AnalyticsParam.TxSentFrom.Earning(
|
||||
blockchain = cryptoCurrency.network.name,
|
||||
token = cryptoCurrency.symbol,
|
||||
feeType = AnalyticsParam.FeeType.Normal,
|
||||
)
|
||||
analytics.send(
|
||||
Basic.TransactionSent(
|
||||
sentFrom = event,
|
||||
memoType = Basic.TransactionSent.MemoType.Null,
|
||||
),
|
||||
)
|
||||
val address = cryptoCurrencyStatus.value.networkAddress?.defaultAddress?.value
|
||||
if (address != null) {
|
||||
yieldSupplyDeactivateUseCase(cryptoCurrency, address)
|
||||
}
|
||||
|
||||
modelScope.launch {
|
||||
params.callback.onTransactionSent()
|
||||
}
|
||||
}
|
||||
|
||||
private fun subscribeOnCurrencyStatusUpdates() {
|
||||
modelScope.launch {
|
||||
feeCryptoCurrencyStatusFlow.update {
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ internal class YieldSupplyStopEarningFeeContentTransformer(
|
|||
maxNetworkFeeFiatValue = TextReference.EMPTY,
|
||||
minTopUpFiatValue = TextReference.EMPTY,
|
||||
feeNoteValue = TextReference.EMPTY,
|
||||
estimatedFiatValue = TextReference.EMPTY,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue