Updated on 2026-08-14
This commit is contained in:
parent
3abed7a11c
commit
57ec369ab0
8 changed files with 86 additions and 136 deletions
|
|
@ -36,15 +36,6 @@ internal object TransactionDomainModule {
|
|||
return GetEthSpecificFeeUseCase(walletManagersFacade = walletManagersFacade)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideTransferGetFeeUseCase(walletManagersFacade: WalletManagersFacade): GetTransferFeeUseCase {
|
||||
return GetTransferFeeUseCase(
|
||||
walletManagersFacade = walletManagersFacade,
|
||||
demoConfig = DemoConfig(),
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideSendTransactionUseCase(
|
||||
|
|
|
|||
|
|
@ -77,13 +77,18 @@ internal class DefaultTransactionRepository(
|
|||
|
||||
override suspend fun createTransferTransaction(
|
||||
amount: Amount,
|
||||
fee: Fee,
|
||||
fee: Fee?,
|
||||
memo: String?,
|
||||
destination: String,
|
||||
userWalletId: UserWalletId,
|
||||
network: Network,
|
||||
): TransactionData.Uncompiled = withContext(coroutineDispatcherProvider.io) {
|
||||
val blockchain = Blockchain.fromId(network.id.value)
|
||||
val walletManager = walletManagersFacade.getOrCreateWalletManager(
|
||||
userWalletId = userWalletId,
|
||||
blockchain = blockchain,
|
||||
derivationPath = network.derivationPath.value,
|
||||
) ?: error("Wallet manager not found")
|
||||
|
||||
val callData = SmartContractCallDataProviderFactory.getTokenTransferCallData(
|
||||
destinationAddress = destination,
|
||||
|
|
@ -102,15 +107,25 @@ internal class DefaultTransactionRepository(
|
|||
null
|
||||
}
|
||||
|
||||
return@withContext createTransaction(
|
||||
amount = amount,
|
||||
fee = fee,
|
||||
memo = null,
|
||||
destination = destination,
|
||||
userWalletId = userWalletId,
|
||||
network = network,
|
||||
txExtras = getMemoExtras(networkId = network.id.value, memo = memo) ?: extras,
|
||||
)
|
||||
return@withContext if (fee != null) {
|
||||
createTransaction(
|
||||
amount = amount,
|
||||
fee = fee,
|
||||
memo = null,
|
||||
destination = destination,
|
||||
userWalletId = userWalletId,
|
||||
network = network,
|
||||
txExtras = getMemoExtras(networkId = network.id.value, memo = memo) ?: extras,
|
||||
)
|
||||
} else {
|
||||
TransactionData.Uncompiled(
|
||||
amount = amount,
|
||||
sourceAddress = walletManager.wallet.address,
|
||||
destinationAddress = destination,
|
||||
extras = getMemoExtras(networkId = network.id.value, memo = memo) ?: extras,
|
||||
fee = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun createApprovalTransaction(
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ interface TransactionRepository {
|
|||
@Suppress("LongParameterList")
|
||||
suspend fun createTransferTransaction(
|
||||
amount: Amount,
|
||||
fee: Fee,
|
||||
fee: Fee?,
|
||||
memo: String?,
|
||||
destination: String,
|
||||
userWalletId: UserWalletId,
|
||||
|
|
|
|||
|
|
@ -38,4 +38,25 @@ class CreateTransferTransactionUseCase(
|
|||
network = network,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* [REDACTED_TODO_COMMENT]
|
||||
*/
|
||||
@Suppress("LongParameterList")
|
||||
suspend operator fun invoke(
|
||||
amount: Amount,
|
||||
memo: String?,
|
||||
destination: String,
|
||||
userWalletId: UserWalletId,
|
||||
network: Network,
|
||||
) = Either.catch {
|
||||
transactionRepository.createTransferTransaction(
|
||||
amount = amount,
|
||||
memo = memo,
|
||||
fee = null,
|
||||
destination = destination,
|
||||
userWalletId = userWalletId,
|
||||
network = network,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,102 +0,0 @@
|
|||
package com.tangem.domain.transaction.usecase
|
||||
|
||||
import arrow.core.raise.catch
|
||||
import arrow.core.raise.either
|
||||
import com.tangem.blockchain.common.*
|
||||
import com.tangem.blockchain.common.smartcontract.SmartContractCallDataProviderFactory
|
||||
import com.tangem.blockchain.extensions.Result
|
||||
import com.tangem.domain.demo.DemoConfig
|
||||
import com.tangem.domain.demo.DemoTransactionSender
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.transaction.error.GetFeeError
|
||||
import com.tangem.domain.transaction.error.mapToFeeError
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import java.math.BigDecimal
|
||||
|
||||
/**
|
||||
* Use case to get transfer transaction fee
|
||||
*
|
||||
* !!!IMPORTANT
|
||||
* Use when transaction data is compiled by us using BlockchainSDK methods
|
||||
*/
|
||||
class GetTransferFeeUseCase(
|
||||
private val walletManagersFacade: WalletManagersFacade,
|
||||
private val demoConfig: DemoConfig,
|
||||
) {
|
||||
suspend operator fun invoke(
|
||||
amount: BigDecimal,
|
||||
destination: String,
|
||||
userWallet: UserWallet,
|
||||
cryptoCurrency: CryptoCurrency,
|
||||
) = either {
|
||||
catch(
|
||||
block = {
|
||||
val amountData = convertCryptoCurrencyToAmount(cryptoCurrency, amount)
|
||||
|
||||
val result = if (demoConfig.isDemoCardId(userWallet.scanResponse.card.cardId)) {
|
||||
demoTransactionSender(userWallet, cryptoCurrency).getFee(
|
||||
amount = amountData,
|
||||
destination = destination,
|
||||
)
|
||||
} else {
|
||||
val walletManager = walletManagersFacade.getOrCreateWalletManager(
|
||||
userWalletId = userWallet.walletId,
|
||||
network = cryptoCurrency.network,
|
||||
)
|
||||
val smartContractCallData = if (amountData.type is AmountType.Token) {
|
||||
SmartContractCallDataProviderFactory.getTokenTransferCallData(
|
||||
amount = amountData,
|
||||
destinationAddress = destination,
|
||||
blockchain = Blockchain.fromId(cryptoCurrency.network.id.value),
|
||||
)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
(walletManager as? TransactionSender)?.getFee(
|
||||
amount = amountData,
|
||||
destination = destination,
|
||||
callData = smartContractCallData,
|
||||
) ?: error("Fee is null")
|
||||
}
|
||||
|
||||
val maybeFee = when (result) {
|
||||
is Result.Success -> result.data
|
||||
is Result.Failure -> raise(result.mapToFeeError())
|
||||
}
|
||||
maybeFee
|
||||
},
|
||||
catch = {
|
||||
raise(GetFeeError.DataError(it))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun demoTransactionSender(
|
||||
userWallet: UserWallet,
|
||||
cryptoCurrency: CryptoCurrency,
|
||||
): DemoTransactionSender {
|
||||
return DemoTransactionSender(
|
||||
walletManagersFacade
|
||||
.getOrCreateWalletManager(userWallet.walletId, cryptoCurrency.network)
|
||||
?: error("WalletManager is null"),
|
||||
)
|
||||
}
|
||||
|
||||
private fun convertCryptoCurrencyToAmount(cryptoCurrency: CryptoCurrency, amount: BigDecimal) = Amount(
|
||||
currencySymbol = cryptoCurrency.symbol,
|
||||
value = amount,
|
||||
decimals = cryptoCurrency.decimals,
|
||||
type = when (cryptoCurrency) {
|
||||
is CryptoCurrency.Coin -> AmountType.Coin
|
||||
is CryptoCurrency.Token -> AmountType.Token(
|
||||
token = Token(
|
||||
symbol = cryptoCurrency.symbol,
|
||||
contractAddress = cryptoCurrency.contractAddress,
|
||||
decimals = cryptoCurrency.decimals,
|
||||
),
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
@ -26,7 +26,7 @@ import com.tangem.domain.settings.NeverShowTapHelpUseCase
|
|||
import com.tangem.domain.tokens.AddCryptoCurrenciesUseCase
|
||||
import com.tangem.domain.tokens.IsAmountSubtractAvailableUseCase
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.transaction.usecase.CreateTransactionUseCase
|
||||
import com.tangem.domain.transaction.usecase.CreateTransferTransactionUseCase
|
||||
import com.tangem.domain.transaction.usecase.SendTransactionUseCase
|
||||
import com.tangem.domain.txhistory.usecase.GetExplorerTransactionUrlUseCase
|
||||
import com.tangem.domain.utils.convertToSdkAmount
|
||||
|
|
@ -74,7 +74,7 @@ internal class SendConfirmModel @Inject constructor(
|
|||
private val router: Router,
|
||||
private val isSendTapHelpEnabledUseCase: IsSendTapHelpEnabledUseCase,
|
||||
private val neverShowTapHelpUseCase: NeverShowTapHelpUseCase,
|
||||
private val createTransactionUseCase: CreateTransactionUseCase,
|
||||
private val createTransferTransactionUseCase: CreateTransferTransactionUseCase,
|
||||
private val sendTransactionUseCase: SendTransactionUseCase,
|
||||
private val saveBlockchainErrorUseCase: SaveBlockchainErrorUseCase,
|
||||
private val getCardInfoUseCase: GetCardInfoUseCase,
|
||||
|
|
@ -326,7 +326,7 @@ internal class SendConfirmModel @Inject constructor(
|
|||
)
|
||||
|
||||
modelScope.launch {
|
||||
createTransactionUseCase(
|
||||
createTransferTransactionUseCase(
|
||||
amount = receivingAmount.convertToSdkAmount(cryptoCurrency),
|
||||
fee = fee,
|
||||
memo = memo,
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.tangem.features.send.v2.send.model
|
|||
import androidx.compose.runtime.Stable
|
||||
import arrow.core.Either
|
||||
import arrow.core.getOrElse
|
||||
import arrow.core.left
|
||||
import com.tangem.blockchain.common.transaction.TransactionFee
|
||||
import com.tangem.common.ui.amountScreen.models.AmountState
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
|
|
@ -28,16 +29,18 @@ import com.tangem.domain.tokens.GetPrimaryCurrencyStatusUpdatesUseCase
|
|||
import com.tangem.domain.tokens.error.CurrencyStatusError
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.transaction.error.GetFeeError
|
||||
import com.tangem.domain.transaction.usecase.GetTransferFeeUseCase
|
||||
import com.tangem.domain.transaction.usecase.CreateTransferTransactionUseCase
|
||||
import com.tangem.domain.transaction.usecase.GetFeeUseCase
|
||||
import com.tangem.domain.utils.convertToSdkAmount
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
||||
import com.tangem.features.send.v2.api.SendComponent
|
||||
import com.tangem.features.send.v2.common.CommonSendRoute
|
||||
import com.tangem.features.send.v2.common.PredefinedValues
|
||||
import com.tangem.features.send.v2.common.SendConfirmAlertFactory
|
||||
import com.tangem.features.send.v2.common.ui.state.ConfirmUM
|
||||
import com.tangem.features.send.v2.common.ui.state.NavigationUM
|
||||
import com.tangem.features.send.v2.send.confirm.SendConfirmComponent
|
||||
import com.tangem.features.send.v2.common.SendConfirmAlertFactory
|
||||
import com.tangem.features.send.v2.send.ui.state.SendUM
|
||||
import com.tangem.features.send.v2.subcomponents.amount.SendAmountComponent
|
||||
import com.tangem.features.send.v2.subcomponents.amount.SendAmountUpdateQRTrigger
|
||||
|
|
@ -80,7 +83,8 @@ internal class SendModel @Inject constructor(
|
|||
private val getCardInfoUseCase: GetCardInfoUseCase,
|
||||
private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase,
|
||||
private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
|
||||
private val getTransferFeeUseCase: GetTransferFeeUseCase,
|
||||
private val createTransferTransactionUseCase: CreateTransferTransactionUseCase,
|
||||
private val getFeeUseCase: GetFeeUseCase,
|
||||
private val sendAmountUpdateQRTrigger: SendAmountUpdateQRTrigger,
|
||||
) : Model(), SendComponentCallback {
|
||||
|
||||
|
|
@ -135,13 +139,23 @@ internal class SendModel @Inject constructor(
|
|||
val destinationUM = uiState.value.destinationUM as? DestinationUM.Content ?: error("Invalid destination")
|
||||
val amountUM = uiState.value.amountUM as? AmountState.Data ?: error("Invalid amount")
|
||||
val enteredDestinationAddress = destinationUM.addressTextField.value
|
||||
val enteredMemo = destinationUM.memoTextField?.value
|
||||
val enteredAmount = amountUM.amountTextField.cryptoAmount.value ?: error("Invalid amount")
|
||||
|
||||
return getTransferFeeUseCase(
|
||||
val transferTransaction = createTransferTransactionUseCase(
|
||||
amount = enteredAmount.convertToSdkAmount(cryptoCurrency),
|
||||
memo = enteredMemo,
|
||||
destination = enteredDestinationAddress,
|
||||
amount = enteredAmount,
|
||||
userWalletId = userWallet.walletId,
|
||||
network = cryptoCurrency.network,
|
||||
).getOrElse {
|
||||
return GetFeeError.DataError(it).left()
|
||||
}
|
||||
|
||||
return getFeeUseCase(
|
||||
transactionData = transferTransaction,
|
||||
userWallet = userWallet,
|
||||
cryptoCurrency = params.currency,
|
||||
network = params.currency.network,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -92,9 +92,9 @@ internal class SendModel @Inject constructor(
|
|||
private val getTxHistoryItemsCountUseCase: GetTxHistoryItemsCountUseCase,
|
||||
private val getTxHistoryItemsUseCase: GetTxHistoryItemsUseCase,
|
||||
private val getFixedTxHistoryItemsUseCase: GetFixedTxHistoryItemsUseCase,
|
||||
private val getTransferFeeUseCase: GetTransferFeeUseCase,
|
||||
private val sendTransactionUseCase: SendTransactionUseCase,
|
||||
private val createTransferTransactionUseCase: CreateTransferTransactionUseCase,
|
||||
private val getFeeUseCase: GetFeeUseCase,
|
||||
private val validateWalletAddressUseCase: ValidateWalletAddressUseCase,
|
||||
private val isAmountSubtractAvailableUseCase: IsAmountSubtractAvailableUseCase,
|
||||
private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
|
||||
|
|
@ -825,12 +825,23 @@ internal class SendModel @Inject constructor(
|
|||
val amountState = uiState.value.getAmountState(isFromConfirmation) as? AmountState.Data ?: return null
|
||||
val recipientState = uiState.value.getRecipientState(isFromConfirmation) ?: return null
|
||||
val amount = amountState.amountTextField.cryptoAmount.value ?: return null
|
||||
val destinationAddress = recipientState.addressTextField.value
|
||||
val memo = recipientState.memoTextField?.value
|
||||
|
||||
return getTransferFeeUseCase.invoke(
|
||||
amount = amount,
|
||||
destination = recipientState.addressTextField.value,
|
||||
val transferTransaction = createTransferTransactionUseCase(
|
||||
amount = amount.convertToSdkAmount(cryptoCurrency),
|
||||
memo = memo,
|
||||
destination = destinationAddress,
|
||||
userWalletId = userWallet.walletId,
|
||||
network = cryptoCurrency.network,
|
||||
).getOrElse {
|
||||
return GetFeeError.DataError(it).left()
|
||||
}
|
||||
|
||||
return getFeeUseCase(
|
||||
transactionData = transferTransaction,
|
||||
userWallet = userWallet,
|
||||
cryptoCurrency = cryptoCurrencyStatus.currency,
|
||||
network = params.currency.network,
|
||||
)
|
||||
}
|
||||
// endregion
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue