Updated on 2026-08-14
This commit is contained in:
parent
9163a956aa
commit
b70933a1e0
47 changed files with 848 additions and 74 deletions
|
|
@ -20,6 +20,7 @@ interface SwapComponent : ComposableContentComponent {
|
|||
val cryptoAmount: BigDecimal,
|
||||
val fiatAmount: BigDecimal,
|
||||
val depositAddress: String,
|
||||
val isWithdrawal: Boolean,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,13 @@
|
|||
package com.tangem.feature.swap.domain.models.ui
|
||||
|
||||
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.transaction.error.SendTransactionError
|
||||
import com.tangem.feature.swap.domain.models.ExpressDataError
|
||||
import com.tangem.feature.swap.domain.models.SwapAmount
|
||||
import com.tangem.feature.swap.domain.models.domain.SwapDataModel
|
||||
import com.tangem.feature.swap.domain.models.domain.SwapProvider
|
||||
import java.math.BigDecimal
|
||||
|
||||
sealed class SwapTransactionState {
|
||||
|
|
@ -16,6 +22,31 @@ sealed class SwapTransactionState {
|
|||
val timestamp: Long,
|
||||
) : SwapTransactionState()
|
||||
|
||||
data class TangemPayWithdrawalData(
|
||||
val cryptoAmount: BigDecimal,
|
||||
val cryptoCurrencyId: CryptoCurrency.RawID,
|
||||
val cexAddress: String,
|
||||
val fromAmount: String?,
|
||||
val fromAmountValue: BigDecimal?,
|
||||
val toAmount: String?,
|
||||
val toAmountValue: BigDecimal?,
|
||||
val storeData: StoreTransactionData,
|
||||
) : SwapTransactionState() {
|
||||
|
||||
data class StoreTransactionData(
|
||||
val currencyToSend: CryptoCurrencyStatus,
|
||||
val currencyToGet: CryptoCurrencyStatus,
|
||||
val fromAccount: Account.CryptoPortfolio?,
|
||||
val toAccount: Account.CryptoPortfolio?,
|
||||
val amount: SwapAmount,
|
||||
val swapProvider: SwapProvider,
|
||||
val swapDataModel: SwapDataModel,
|
||||
val txExternalUrl: String?,
|
||||
val txExternalId: String?,
|
||||
val averageDuration: Int?,
|
||||
)
|
||||
}
|
||||
|
||||
data object DemoMode : SwapTransactionState()
|
||||
|
||||
sealed class Error : SwapTransactionState() {
|
||||
|
|
|
|||
|
|
@ -61,7 +61,8 @@ interface SwapInteractor {
|
|||
* @param currencyToSend [Currency]
|
||||
* @param currencyToGet [Currency]
|
||||
* @param amountToSwap amount to swap
|
||||
* @param fee for tx
|
||||
* @param fee for tx (can be null only for tangem pay withdrawal)
|
||||
|
||||
* @return [SwapTransactionState]
|
||||
*/
|
||||
@Suppress("LongParameterList")
|
||||
|
|
@ -75,8 +76,9 @@ interface SwapInteractor {
|
|||
toAccount: Account.CryptoPortfolio?,
|
||||
amountToSwap: String,
|
||||
includeFeeInAmount: IncludeFeeInAmount,
|
||||
fee: TxFee,
|
||||
fee: TxFee?,
|
||||
expressOperationType: ExpressOperationType,
|
||||
isTangemPayWithdrawal: Boolean,
|
||||
): SwapTransactionState
|
||||
|
||||
// suspend fun updateQuotesStateWithSelectedFee(
|
||||
|
|
@ -115,6 +117,21 @@ interface SwapInteractor {
|
|||
|
||||
fun getNativeToken(networkId: String): CryptoCurrency
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
suspend fun storeSwapTransaction(
|
||||
currencyToSend: CryptoCurrencyStatus,
|
||||
currencyToGet: CryptoCurrencyStatus,
|
||||
fromAccount: Account.CryptoPortfolio?,
|
||||
toAccount: Account.CryptoPortfolio?,
|
||||
amount: SwapAmount,
|
||||
swapProvider: SwapProvider,
|
||||
swapDataModel: SwapDataModel,
|
||||
timestamp: Long,
|
||||
txExternalUrl: String? = null,
|
||||
txExternalId: String? = null,
|
||||
averageDuration: Int? = null,
|
||||
)
|
||||
|
||||
interface Factory {
|
||||
fun create(selectedWalletId: UserWalletId): SwapInteractor
|
||||
}
|
||||
|
|
|
|||
|
|
@ -709,6 +709,7 @@ internal class SwapInteractorImpl @AssistedInject constructor(
|
|||
return result
|
||||
}
|
||||
|
||||
@Suppress("NullableToStringCall")
|
||||
override suspend fun onSwap(
|
||||
swapProvider: SwapProvider,
|
||||
swapData: SwapDataModel?,
|
||||
|
|
@ -718,8 +719,9 @@ internal class SwapInteractorImpl @AssistedInject constructor(
|
|||
toAccount: Account.CryptoPortfolio?,
|
||||
amountToSwap: String,
|
||||
includeFeeInAmount: IncludeFeeInAmount,
|
||||
fee: TxFee,
|
||||
fee: TxFee?,
|
||||
expressOperationType: ExpressOperationType,
|
||||
isTangemPayWithdrawal: Boolean,
|
||||
): SwapTransactionState {
|
||||
Timber.i(
|
||||
"""
|
||||
|
|
@ -757,6 +759,7 @@ internal class SwapInteractorImpl @AssistedInject constructor(
|
|||
txFee = fee,
|
||||
swapProvider = swapProvider,
|
||||
expressOperationType = expressOperationType,
|
||||
isTangemPayWithdrawal = isTangemPayWithdrawal,
|
||||
)
|
||||
}
|
||||
ExchangeProviderType.DEX, ExchangeProviderType.DEX_BRIDGE -> {
|
||||
|
|
@ -773,6 +776,7 @@ internal class SwapInteractorImpl @AssistedInject constructor(
|
|||
amountToSwap = amountToSwap,
|
||||
)
|
||||
} else {
|
||||
if (fee == null) return SwapTransactionState.Error.UnknownError
|
||||
onSwapDex(
|
||||
provider = swapProvider,
|
||||
networkId = currencyToSend.currency.network.backendId,
|
||||
|
|
@ -978,16 +982,17 @@ internal class SwapInteractorImpl @AssistedInject constructor(
|
|||
).getOrNull() ?: error("failed to create extras")
|
||||
}
|
||||
|
||||
@Suppress("LongMethod")
|
||||
@Suppress("LongMethod", "CanBeNonNullable")
|
||||
private suspend fun onSwapCex(
|
||||
currencyToSend: CryptoCurrencyStatus,
|
||||
currencyToGet: CryptoCurrencyStatus,
|
||||
fromAccount: Account.CryptoPortfolio?,
|
||||
toAccount: Account.CryptoPortfolio?,
|
||||
amount: SwapAmount,
|
||||
txFee: TxFee,
|
||||
txFee: TxFee?,
|
||||
swapProvider: SwapProvider,
|
||||
expressOperationType: ExpressOperationType,
|
||||
isTangemPayWithdrawal: Boolean,
|
||||
): SwapTransactionState {
|
||||
val exchangeData = repository.getExchangeData(
|
||||
userWallet = userWallet,
|
||||
|
|
@ -1010,6 +1015,33 @@ internal class SwapInteractorImpl @AssistedInject constructor(
|
|||
val exchangeDataCex =
|
||||
exchangeData.transaction as? ExpressTransactionModel.CEX ?: return SwapTransactionState.Error.UnknownError
|
||||
|
||||
if (isTangemPayWithdrawal) {
|
||||
return SwapTransactionState.TangemPayWithdrawalData(
|
||||
cryptoAmount = amount.value,
|
||||
cryptoCurrencyId = requireNotNull(currencyToSend.currency.id.rawCurrencyId),
|
||||
cexAddress = exchangeDataCex.txTo,
|
||||
fromAmount = amount.toStringWithRightOffset(),
|
||||
fromAmountValue = amount.value,
|
||||
toAmount = amountFormatter.formatSwapAmountToUI(
|
||||
exchangeData.toTokenAmount,
|
||||
currencyToGet.currency.symbol,
|
||||
),
|
||||
toAmountValue = exchangeData.toTokenAmount.value,
|
||||
storeData = SwapTransactionState.TangemPayWithdrawalData.StoreTransactionData(
|
||||
currencyToSend = currencyToSend,
|
||||
currencyToGet = currencyToGet,
|
||||
fromAccount = fromAccount,
|
||||
toAccount = toAccount,
|
||||
amount = amount,
|
||||
swapProvider = swapProvider,
|
||||
swapDataModel = exchangeData,
|
||||
txExternalUrl = "",
|
||||
txExternalId = exchangeDataCex.externalTxId,
|
||||
averageDuration = null,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
val userWallet = userWallet
|
||||
if (userWallet is UserWallet.Cold && isDemoCardUseCase(userWallet.scanResponse.card.cardId)) {
|
||||
return SwapTransactionState.Error.UnknownError
|
||||
|
|
@ -1017,7 +1049,7 @@ internal class SwapInteractorImpl @AssistedInject constructor(
|
|||
|
||||
val txData = createTransferTransactionUseCase(
|
||||
amount = amount.value.convertToSdkAmount(currencyToSend),
|
||||
fee = txFee.fee,
|
||||
fee = requireNotNull(txFee).fee,
|
||||
memo = exchangeDataCex.txExtraId,
|
||||
destination = exchangeDataCex.txTo,
|
||||
userWalletId = userWalletId,
|
||||
|
|
@ -1087,7 +1119,7 @@ internal class SwapInteractorImpl @AssistedInject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
private suspend fun storeSwapTransaction(
|
||||
override suspend fun storeSwapTransaction(
|
||||
currencyToSend: CryptoCurrencyStatus,
|
||||
currencyToGet: CryptoCurrencyStatus,
|
||||
fromAccount: Account.CryptoPortfolio?,
|
||||
|
|
@ -1096,9 +1128,9 @@ internal class SwapInteractorImpl @AssistedInject constructor(
|
|||
swapProvider: SwapProvider,
|
||||
swapDataModel: SwapDataModel,
|
||||
timestamp: Long,
|
||||
txExternalUrl: String? = null,
|
||||
txExternalId: String? = null,
|
||||
averageDuration: Int? = null,
|
||||
txExternalUrl: String?,
|
||||
txExternalId: String?,
|
||||
averageDuration: Int?,
|
||||
) {
|
||||
swapTransactionRepository.storeTransaction(
|
||||
userWalletId = userWalletId,
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ dependencies {
|
|||
implementation(projects.common.routing)
|
||||
implementation(projects.common.ui)
|
||||
implementation(projects.core.decompose) // For Route supertype
|
||||
implementation(projects.core.error)
|
||||
|
||||
/** Domain modules **/
|
||||
implementation(projects.domain.models)
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ import com.tangem.domain.settings.usercountry.GetUserCountryUseCase
|
|||
import com.tangem.domain.settings.usercountry.models.UserCountry
|
||||
import com.tangem.domain.settings.usercountry.models.needApplyFCARestrictions
|
||||
import com.tangem.domain.tangempay.GetTangemPayCurrencyStatusUseCase
|
||||
import com.tangem.domain.tangempay.TangemPayWithdrawUseCase
|
||||
import com.tangem.domain.tokens.GetFeePaidCryptoCurrencyStatusSyncUseCase
|
||||
import com.tangem.domain.tokens.GetMinimumTransactionAmountSyncUseCase
|
||||
import com.tangem.domain.tokens.GetSingleCryptoCurrencyStatusUseCase
|
||||
|
|
@ -115,6 +116,7 @@ internal class SwapModel @Inject constructor(
|
|||
private val getAccountCurrencyStatusUseCase: GetAccountCurrencyStatusUseCase,
|
||||
private val accountsFeatureToggles: AccountsFeatureToggles,
|
||||
private val getTangemPayCurrencyStatusUseCase: GetTangemPayCurrencyStatusUseCase,
|
||||
private val tangemPayWithdrawUseCase: TangemPayWithdrawUseCase,
|
||||
) : Model() {
|
||||
|
||||
private val params = paramsContainer.require<SwapComponent.Params>()
|
||||
|
|
@ -555,6 +557,7 @@ internal class SwapModel @Inject constructor(
|
|||
selectedFeeType = dataState.selectedFee?.feeType ?: FeeType.NORMAL,
|
||||
isReverseSwapPossible = isReverseSwapPossible(),
|
||||
needApplyFCARestrictions = userCountry.needApplyFCARestrictions(),
|
||||
hideFee = tangemPayInput?.isWithdrawal == true,
|
||||
)
|
||||
if (uiState.notifications.any { it is SwapNotificationUM.Error.UnableToCoverFeeWarning }) {
|
||||
analyticsEventHandler.send(
|
||||
|
|
@ -702,7 +705,7 @@ internal class SwapModel @Inject constructor(
|
|||
val fromCurrency = requireNotNull(dataState.fromCryptoCurrency)
|
||||
val fee = dataState.selectedFee
|
||||
|
||||
if (fee == null) {
|
||||
if (fee == null && tangemPayInput?.isWithdrawal != true) {
|
||||
makeDefaultAlert(resourceReference(R.string.swapping_fee_estimation_error_text))
|
||||
return
|
||||
}
|
||||
|
|
@ -719,13 +722,18 @@ internal class SwapModel @Inject constructor(
|
|||
includeFeeInAmount = lastLoadedQuotesState.preparedSwapConfigState.includeFeeInAmount,
|
||||
fee = fee,
|
||||
expressOperationType = ExpressOperationType.SWAP,
|
||||
isTangemPayWithdrawal = tangemPayInput?.isWithdrawal == true,
|
||||
)
|
||||
}.onSuccess {
|
||||
when (it) {
|
||||
}.onSuccess { swapTransactionState ->
|
||||
when (swapTransactionState) {
|
||||
is SwapTransactionState.TxSent -> {
|
||||
if (fee == null) {
|
||||
makeDefaultAlert(resourceReference(R.string.swapping_fee_estimation_error_text))
|
||||
return@onSuccess
|
||||
}
|
||||
sendSuccessSwapEvent(fromCurrency.currency, fee.feeType)
|
||||
val url = getExplorerTransactionUrlUseCase(
|
||||
txHash = it.txHash,
|
||||
txHash = swapTransactionState.txHash,
|
||||
networkId = fromCurrency.currency.network.id,
|
||||
).getOrElse {
|
||||
Timber.i("tx hash explore not supported")
|
||||
|
|
@ -735,11 +743,11 @@ internal class SwapModel @Inject constructor(
|
|||
updateWalletBalance()
|
||||
uiState = stateBuilder.createSuccessState(
|
||||
uiState = uiState,
|
||||
swapTransactionState = it,
|
||||
swapTransactionState = swapTransactionState,
|
||||
dataState = dataState,
|
||||
txUrl = url,
|
||||
onExploreClick = {
|
||||
if (it.txHash.isNotEmpty()) {
|
||||
if (swapTransactionState.txHash.isNotEmpty()) {
|
||||
urlOpener.openUrl(url)
|
||||
}
|
||||
analyticsEventHandler.send(
|
||||
|
|
@ -747,7 +755,7 @@ internal class SwapModel @Inject constructor(
|
|||
)
|
||||
},
|
||||
onStatusClick = {
|
||||
val txExternalUrl = it.txExternalUrl
|
||||
val txExternalUrl = swapTransactionState.txExternalUrl
|
||||
if (!txExternalUrl.isNullOrBlank()) {
|
||||
urlOpener.openUrl(txExternalUrl)
|
||||
analyticsEventHandler.send(
|
||||
|
|
@ -771,12 +779,15 @@ internal class SwapModel @Inject constructor(
|
|||
startLoadingQuotesFromLastState()
|
||||
uiState = stateBuilder.createErrorTransactionAlert(
|
||||
uiState = uiState,
|
||||
error = it,
|
||||
error = swapTransactionState,
|
||||
onDismiss = { uiState = stateBuilder.clearAlert(uiState) },
|
||||
onSupportClick = ::onFailedTxEmailClick,
|
||||
isReverseSwapPossible = isReverseSwapPossible(),
|
||||
)
|
||||
}
|
||||
is SwapTransactionState.TangemPayWithdrawalData -> {
|
||||
processTangemPayWithdrawal(swapTransactionState = swapTransactionState)
|
||||
}
|
||||
}
|
||||
}.onFailure {
|
||||
Timber.e(it)
|
||||
|
|
@ -786,6 +797,40 @@ internal class SwapModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private suspend fun processTangemPayWithdrawal(swapTransactionState: SwapTransactionState.TangemPayWithdrawalData) {
|
||||
tangemPayWithdrawUseCase(
|
||||
userWalletId = userWalletId,
|
||||
cryptoAmount = swapTransactionState.cryptoAmount,
|
||||
cryptoCurrencyId = swapTransactionState.cryptoCurrencyId,
|
||||
receiverCexAddress = swapTransactionState.cexAddress,
|
||||
)
|
||||
.onLeft {
|
||||
startLoadingQuotesFromLastState()
|
||||
makeDefaultAlert()
|
||||
}
|
||||
.onRight {
|
||||
swapInteractor.storeSwapTransaction(
|
||||
currencyToSend = swapTransactionState.storeData.currencyToSend,
|
||||
currencyToGet = swapTransactionState.storeData.currencyToGet,
|
||||
fromAccount = swapTransactionState.storeData.fromAccount,
|
||||
toAccount = swapTransactionState.storeData.toAccount,
|
||||
amount = swapTransactionState.storeData.amount,
|
||||
swapProvider = swapTransactionState.storeData.swapProvider,
|
||||
swapDataModel = swapTransactionState.storeData.swapDataModel,
|
||||
txExternalUrl = "",
|
||||
timestamp = System.currentTimeMillis(),
|
||||
txExternalId = swapTransactionState.storeData.txExternalId,
|
||||
averageDuration = null,
|
||||
)
|
||||
uiState = stateBuilder.createTangemPayWithdrawalSuccessState(
|
||||
uiState = uiState,
|
||||
swapTransactionState = swapTransactionState,
|
||||
dataState = dataState,
|
||||
)
|
||||
swapRouter.openScreen(SwapNavScreen.Success)
|
||||
}
|
||||
}
|
||||
|
||||
private fun sendSuccessEvent() {
|
||||
val provider = dataState.selectedProvider ?: return
|
||||
val fee = dataState.selectedFee?.feeType ?: return
|
||||
|
|
@ -804,6 +849,7 @@ internal class SwapModel @Inject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
@Suppress("LongMethod")
|
||||
private fun givePermissionsToSwap() {
|
||||
modelScope.launch(dispatchers.main) {
|
||||
runCatching {
|
||||
|
|
@ -840,8 +886,8 @@ internal class SwapModel @Inject constructor(
|
|||
spenderAddress = approveDataModel.spenderAddress,
|
||||
),
|
||||
)
|
||||
}.onSuccess {
|
||||
when (it) {
|
||||
}.onSuccess { swapTransactionState ->
|
||||
when (swapTransactionState) {
|
||||
is SwapTransactionState.TxSent -> {
|
||||
sendApproveSuccessEvent(fromToken, feeForPermission.feeType, approveType)
|
||||
updateWalletBalance()
|
||||
|
|
@ -852,7 +898,7 @@ internal class SwapModel @Inject constructor(
|
|||
is SwapTransactionState.Error -> {
|
||||
uiState = stateBuilder.createErrorTransactionAlert(
|
||||
uiState = uiState,
|
||||
error = it,
|
||||
error = swapTransactionState,
|
||||
onDismiss = { uiState = stateBuilder.clearAlert(uiState) },
|
||||
onSupportClick = ::onFailedTxEmailClick,
|
||||
isReverseSwapPossible = isReverseSwapPossible(),
|
||||
|
|
@ -865,6 +911,9 @@ internal class SwapModel @Inject constructor(
|
|||
isReverseSwapPossible = isReverseSwapPossible(),
|
||||
)
|
||||
}
|
||||
is SwapTransactionState.TangemPayWithdrawalData -> {
|
||||
processTangemPayWithdrawal(swapTransactionState = swapTransactionState)
|
||||
}
|
||||
}
|
||||
}.onFailure { makeDefaultAlert() }
|
||||
}.onFailure {
|
||||
|
|
@ -1475,7 +1524,17 @@ internal class SwapModel @Inject constructor(
|
|||
} else {
|
||||
groupToFind.available.find { idToFind == it.currencyStatus.currency.id.value }
|
||||
?.providers
|
||||
}.orEmpty()
|
||||
}
|
||||
?.filterForTangemPayWithdrawal()
|
||||
.orEmpty()
|
||||
}
|
||||
|
||||
private fun List<SwapProvider>.filterForTangemPayWithdrawal(): List<SwapProvider> {
|
||||
return if (tangemPayInput?.isWithdrawal == true) {
|
||||
filter { it.type == ExchangeProviderType.CEX }
|
||||
} else {
|
||||
this
|
||||
}
|
||||
}
|
||||
|
||||
private fun Map<SwapProvider, SwapState>.getLastLoadedSuccessStates(): SuccessLoadedSwapData {
|
||||
|
|
|
|||
|
|
@ -92,12 +92,14 @@ internal class SwapNotificationsFactory(
|
|||
return updatedNotifications.toPersistentList()
|
||||
}
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
fun getConfirmationStateNotifications(
|
||||
quoteModel: SwapState.QuotesLoadedState,
|
||||
fromToken: CryptoCurrency,
|
||||
feeCryptoCurrencyStatus: CryptoCurrencyStatus?,
|
||||
selectedFeeType: FeeType,
|
||||
providerName: String,
|
||||
hideFee: Boolean,
|
||||
): ImmutableList<NotificationUM> {
|
||||
val warnings = buildList {
|
||||
maybeAddRentExemptionError(quoteModel)
|
||||
|
|
@ -105,7 +107,7 @@ internal class SwapNotificationsFactory(
|
|||
maybeAddNeedReserveToCreateAccountWarning(quoteModel)
|
||||
maybeAddPermissionNeededWarning(quoteModel, fromToken, providerName)
|
||||
maybeAddNetworkFeeCoverageWarning(quoteModel, selectedFeeType)
|
||||
maybeAddUnableCoverFeeWarning(quoteModel, fromToken)
|
||||
maybeAddUnableCoverFeeWarning(quoteModel, fromToken, hideFee)
|
||||
maybeAddTransactionInProgressWarning(quoteModel)
|
||||
}
|
||||
return warnings.toPersistentList()
|
||||
|
|
@ -284,7 +286,9 @@ internal class SwapNotificationsFactory(
|
|||
private fun MutableList<NotificationUM>.maybeAddUnableCoverFeeWarning(
|
||||
quoteModel: SwapState.QuotesLoadedState,
|
||||
fromToken: CryptoCurrency,
|
||||
hideFee: Boolean,
|
||||
) {
|
||||
if (hideFee) return
|
||||
val feeEnoughState = quoteModel.preparedSwapConfigState.feeState as? SwapFeeState.NotEnough ?: return
|
||||
val needShowCoverWarning = quoteModel.preparedSwapConfigState.isBalanceEnough &&
|
||||
quoteModel.permissionState !is PermissionDataState.PermissionLoading &&
|
||||
|
|
|
|||
|
|
@ -277,6 +277,7 @@ internal class StateBuilder(
|
|||
selectedFeeType: FeeType,
|
||||
isReverseSwapPossible: Boolean,
|
||||
needApplyFCARestrictions: Boolean,
|
||||
hideFee: Boolean,
|
||||
): SwapStateHolder {
|
||||
if (uiStateHolder.sendCardData !is SwapCardState.SwapCardData) return uiStateHolder
|
||||
if (uiStateHolder.receiveCardData !is SwapCardState.SwapCardData) return uiStateHolder
|
||||
|
|
@ -286,8 +287,9 @@ internal class StateBuilder(
|
|||
feeCryptoCurrencyStatus = feeCryptoCurrencyStatus,
|
||||
selectedFeeType = selectedFeeType,
|
||||
providerName = swapProvider.name,
|
||||
hideFee = hideFee,
|
||||
)
|
||||
val feeState = createFeeState(quoteModel.txFee, selectedFeeType)
|
||||
val feeState = if (hideFee) FeeItemState.Empty else createFeeState(quoteModel.txFee, selectedFeeType)
|
||||
val fromCurrencyStatus = quoteModel.fromTokenInfo.cryptoCurrencyStatus
|
||||
val toCurrencyStatus = quoteModel.toTokenInfo.cryptoCurrencyStatus
|
||||
val isInsufficientFunds = isInsufficientFundsCondition(quoteModel)
|
||||
|
|
@ -853,6 +855,45 @@ internal class StateBuilder(
|
|||
)
|
||||
}
|
||||
|
||||
fun createTangemPayWithdrawalSuccessState(
|
||||
uiState: SwapStateHolder,
|
||||
swapTransactionState: SwapTransactionState.TangemPayWithdrawalData,
|
||||
dataState: SwapProcessDataState,
|
||||
): SwapStateHolder {
|
||||
val fromCryptoCurrency = requireNotNull(dataState.fromCryptoCurrency)
|
||||
val toCryptoCurrency = requireNotNull(dataState.toCryptoCurrency)
|
||||
val fromAmount = swapTransactionState.fromAmountValue ?: BigDecimal.ZERO
|
||||
val toAmount = swapTransactionState.toAmountValue ?: BigDecimal.ZERO
|
||||
val providerState = uiState.providerState as ProviderState.Content
|
||||
|
||||
val fromFiatAmount = getFormattedFiatAmount(fromCryptoCurrency.value.fiatRate?.multiply(fromAmount))
|
||||
val toFiatAmount = getFormattedFiatAmount(toCryptoCurrency.value.fiatRate?.multiply(toAmount))
|
||||
|
||||
val shouldShowStatus = providerState.type == ExchangeProviderType.CEX.providerName
|
||||
return uiState.copy(
|
||||
successState = SwapSuccessStateHolder(
|
||||
timestamp = System.currentTimeMillis(),
|
||||
txUrl = "",
|
||||
providerName = stringReference(providerState.name),
|
||||
providerType = stringReference(providerState.type),
|
||||
showStatusButton = shouldShowStatus,
|
||||
providerIcon = providerState.iconUrl,
|
||||
rate = providerState.subtitle,
|
||||
fee = TextReference.EMPTY,
|
||||
fromTitle = getFromCardAccountTitle(fromAccount = dataState.fromAccount),
|
||||
toTitle = getToCardAccountTitle(toAccount = dataState.toAccount),
|
||||
fromTokenAmount = stringReference(swapTransactionState.fromAmount.orEmpty()),
|
||||
toTokenAmount = stringReference(swapTransactionState.toAmount.orEmpty()),
|
||||
fromTokenFiatAmount = stringReference(fromFiatAmount),
|
||||
toTokenFiatAmount = stringReference(toFiatAmount),
|
||||
fromTokenIconState = iconStateConverter.convert(fromCryptoCurrency),
|
||||
toTokenIconState = iconStateConverter.convert(toCryptoCurrency),
|
||||
onExploreButtonClick = {},
|
||||
onStatusButtonClick = {},
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fun createErrorTransactionAlert(
|
||||
uiState: SwapStateHolder,
|
||||
error: SwapTransactionState.Error,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue