Updated on 2026-08-14
This commit is contained in:
parent
86af90fd92
commit
d31d3f8a9b
8 changed files with 82 additions and 172 deletions
|
|
@ -1,19 +1,21 @@
|
|||
package com.tangem.domain.transaction.usecase.gasless
|
||||
|
||||
import arrow.core.Either
|
||||
import arrow.core.getOrElse
|
||||
import arrow.core.raise.Raise
|
||||
import arrow.core.raise.catch
|
||||
import arrow.core.raise.either
|
||||
import com.tangem.blockchain.blockchains.ethereum.EthereumWalletManager
|
||||
import com.tangem.blockchain.common.transaction.Fee
|
||||
import com.tangem.blockchain.common.transaction.TransactionFee
|
||||
import com.tangem.domain.account.models.AccountStatusList
|
||||
import com.tangem.domain.account.status.supplier.SingleAccountStatusListSupplier
|
||||
import com.tangem.domain.account.status.utils.CryptoCurrencyStatusOperations.getCoinStatus
|
||||
import com.tangem.domain.demo.models.DemoConfig
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.tokens.GetMultiCryptoCurrencyStatusUseCase
|
||||
import com.tangem.domain.tokens.repository.CurrenciesRepository
|
||||
import com.tangem.domain.tokens.repository.CurrencyChecksRepository
|
||||
import com.tangem.domain.transaction.GaslessTransactionRepository
|
||||
import com.tangem.domain.transaction.error.GetFeeError
|
||||
|
|
@ -29,8 +31,7 @@ class EstimateFeeForGaslessTxUseCase(
|
|||
private val walletManagersFacade: WalletManagersFacade,
|
||||
private val demoConfig: DemoConfig,
|
||||
private val gaslessTransactionRepository: GaslessTransactionRepository,
|
||||
private val currenciesRepository: CurrenciesRepository,
|
||||
private val getMultiCryptoCurrencyStatusUseCase: GetMultiCryptoCurrencyStatusUseCase,
|
||||
private val singleAccountStatusListSupplier: SingleAccountStatusListSupplier,
|
||||
private val estimateFeeUseCase: EstimateFeeUseCase,
|
||||
private val currencyChecksRepository: CurrencyChecksRepository,
|
||||
) {
|
||||
|
|
@ -50,11 +51,13 @@ class EstimateFeeForGaslessTxUseCase(
|
|||
catch(
|
||||
block = {
|
||||
val network = sendingTokenCurrencyStatus.currency.network
|
||||
val nativeCurrency = currenciesRepository.getNetworkCoin(
|
||||
userWalletId = userWallet.walletId,
|
||||
networkId = network.id,
|
||||
derivationPath = network.derivationPath,
|
||||
)
|
||||
|
||||
val accountStatusList = singleAccountStatusListSupplier.getSyncOrNull(userWallet.walletId)
|
||||
?: raiseIllegalStateError("AccountStatusList is null for ${userWallet.walletId}")
|
||||
|
||||
val nativeCurrencyStatus = accountStatusList.getCoinStatus(network).getOrElse {
|
||||
raiseIllegalStateError("No native currency found: ${network.id}")
|
||||
}
|
||||
|
||||
if (!currencyChecksRepository.isNetworkSupportedForGaslessTx(network)) {
|
||||
estimateFeeUseCase.invoke(
|
||||
|
|
@ -66,7 +69,7 @@ class EstimateFeeForGaslessTxUseCase(
|
|||
ifRight = { fee ->
|
||||
return@either TransactionFeeExtended(
|
||||
transactionFee = fee,
|
||||
feeTokenId = nativeCurrency.id,
|
||||
feeTokenId = nativeCurrencyStatus.currency.id,
|
||||
)
|
||||
},
|
||||
)
|
||||
|
|
@ -81,9 +84,9 @@ class EstimateFeeForGaslessTxUseCase(
|
|||
).bind()
|
||||
|
||||
selectFeePaymentStrategy(
|
||||
userWallet = userWallet,
|
||||
accountStatusList = accountStatusList,
|
||||
walletManager = walletManager,
|
||||
nativeCurrency = nativeCurrency,
|
||||
nativeCurrencyStatus = nativeCurrencyStatus,
|
||||
network = network,
|
||||
initialFee = initialFee,
|
||||
)
|
||||
|
|
@ -110,25 +113,17 @@ class EstimateFeeForGaslessTxUseCase(
|
|||
}
|
||||
|
||||
private suspend fun Raise<GetFeeError>.selectFeePaymentStrategy(
|
||||
userWallet: UserWallet,
|
||||
accountStatusList: AccountStatusList,
|
||||
walletManager: EthereumWalletManager,
|
||||
nativeCurrency: CryptoCurrency,
|
||||
nativeCurrencyStatus: CryptoCurrencyStatus,
|
||||
network: Network,
|
||||
initialFee: TransactionFee,
|
||||
): TransactionFeeExtended {
|
||||
val feeValue = initialFee.normal.amount.value ?: raise(GetFeeError.UnknownError)
|
||||
|
||||
val userCurrenciesStatuses = getMultiCryptoCurrencyStatusUseCase.invokeMultiWalletSync(
|
||||
userWallet.walletId,
|
||||
).getOrNull() ?: raiseIllegalStateError("currencies list is null for userWalletId=${userWallet.walletId}")
|
||||
|
||||
val networkCurrenciesStatuses = userCurrenciesStatuses.filter {
|
||||
it.currency.network.id == network.id
|
||||
}
|
||||
|
||||
val nativeCurrencyStatus = networkCurrenciesStatuses.find {
|
||||
it.currency.id == nativeCurrency.id
|
||||
} ?: raiseIllegalStateError("native currency not found for network ${network.id}")
|
||||
val networkCurrenciesStatuses = accountStatusList
|
||||
.flattenCurrencies()
|
||||
.filter { it.currency.network.id == network.id }
|
||||
|
||||
val nativeBalance = nativeCurrencyStatus.value.amount ?: BigDecimal.ZERO
|
||||
return if (nativeBalance >= feeValue) {
|
||||
|
|
|
|||
|
|
@ -1,17 +1,18 @@
|
|||
package com.tangem.domain.transaction.usecase.gasless
|
||||
|
||||
import arrow.core.Either
|
||||
import arrow.core.getOrElse
|
||||
import arrow.core.raise.Raise
|
||||
import arrow.core.raise.catch
|
||||
import arrow.core.raise.either
|
||||
import com.tangem.blockchain.blockchains.ethereum.EthereumWalletManager
|
||||
import com.tangem.blockchain.common.transaction.Fee
|
||||
import com.tangem.domain.account.status.supplier.SingleAccountStatusListSupplier
|
||||
import com.tangem.domain.account.status.utils.CryptoCurrencyStatusOperations.getCoinStatus
|
||||
import com.tangem.domain.demo.models.DemoConfig
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.tokens.GetMultiCryptoCurrencyStatusUseCase
|
||||
import com.tangem.domain.tokens.repository.CurrenciesRepository
|
||||
import com.tangem.domain.tokens.repository.CurrencyChecksRepository
|
||||
import com.tangem.domain.transaction.GaslessTransactionRepository
|
||||
import com.tangem.domain.transaction.error.GetFeeError
|
||||
|
|
@ -25,8 +26,7 @@ class EstimateFeeForTokenUseCase(
|
|||
private val gaslessTransactionRepository: GaslessTransactionRepository,
|
||||
private val walletManagersFacade: WalletManagersFacade,
|
||||
private val demoConfig: DemoConfig,
|
||||
private val currenciesRepository: CurrenciesRepository,
|
||||
private val getMultiCryptoCurrencyStatusUseCase: GetMultiCryptoCurrencyStatusUseCase,
|
||||
private val singleAccountStatusListSupplier: SingleAccountStatusListSupplier,
|
||||
private val currencyChecksRepository: CurrencyChecksRepository,
|
||||
) {
|
||||
|
||||
|
|
@ -61,21 +61,12 @@ class EstimateFeeForTokenUseCase(
|
|||
error = "only Fee.Ethereum supported, but was different",
|
||||
)
|
||||
|
||||
val nativeCurrency = currenciesRepository.getNetworkCoin(
|
||||
userWalletId = userWallet.walletId,
|
||||
networkId = token.network.id,
|
||||
derivationPath = token.network.derivationPath,
|
||||
)
|
||||
val accountStatusList = singleAccountStatusListSupplier.getSyncOrNull(userWallet.walletId)
|
||||
?: raiseIllegalStateError("AccountStatusList is null for ${userWallet.walletId}")
|
||||
|
||||
val userCurrenciesStatusesByNetwork = getMultiCryptoCurrencyStatusUseCase.invokeMultiWalletSync(
|
||||
userWallet.walletId,
|
||||
).getOrNull()?.filter {
|
||||
it.currency.network.id == token.network.id
|
||||
} ?: raiseIllegalStateError("currencies list is null for userWalletId=${userWallet.walletId}")
|
||||
|
||||
val nativeCurrencyStatus = userCurrenciesStatusesByNetwork.find {
|
||||
it.currency.id == nativeCurrency.id
|
||||
} ?: raiseIllegalStateError("native currency not found for network ${token.network.id}")
|
||||
val nativeCurrencyStatus = accountStatusList.getCoinStatus(token.network).getOrElse {
|
||||
raiseIllegalStateError("No native currency found: ${token.network.id}")
|
||||
}
|
||||
|
||||
val walletManager = prepareWalletManager(userWallet, token.network)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,24 +1,23 @@
|
|||
package com.tangem.domain.transaction.usecase.gasless
|
||||
|
||||
import arrow.core.Either
|
||||
import arrow.core.raise.Raise
|
||||
import arrow.core.getOrElse
|
||||
import arrow.core.raise.catch
|
||||
import arrow.core.raise.either
|
||||
import com.tangem.domain.account.status.supplier.SingleAccountStatusListSupplier
|
||||
import com.tangem.domain.account.status.utils.CryptoCurrencyStatusOperations.getCoinStatus
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.tokens.GetMultiCryptoCurrencyStatusUseCase
|
||||
import com.tangem.domain.tokens.repository.CurrenciesRepository
|
||||
import com.tangem.domain.tokens.repository.CurrencyChecksRepository
|
||||
import com.tangem.domain.transaction.GaslessTransactionRepository
|
||||
import com.tangem.domain.transaction.error.GetFeeError
|
||||
import com.tangem.domain.transaction.raiseIllegalStateError
|
||||
|
||||
class GetAvailableFeeTokensUseCase(
|
||||
private val singleAccountStatusListSupplier: SingleAccountStatusListSupplier,
|
||||
private val gaslessTransactionRepository: GaslessTransactionRepository,
|
||||
private val currenciesRepository: CurrenciesRepository,
|
||||
private val getMultiCryptoCurrencyStatusUseCase: GetMultiCryptoCurrencyStatusUseCase,
|
||||
private val currencyChecksRepository: CurrencyChecksRepository,
|
||||
) {
|
||||
|
||||
|
|
@ -34,12 +33,14 @@ class GetAvailableFeeTokensUseCase(
|
|||
return either {
|
||||
catch(
|
||||
block = {
|
||||
val userCurrenciesStatuses = getMultiCryptoCurrencyStatusUseCase.invokeMultiWalletSync(
|
||||
userWallet.walletId,
|
||||
).getOrNull()
|
||||
?: raiseIllegalStateError("currencies list is null for userWalletId=${userWallet.walletId}")
|
||||
val accountStatusList = singleAccountStatusListSupplier.getSyncOrNull(userWallet.walletId)
|
||||
?: raiseIllegalStateError("AccountStatusList is null for ${userWallet.walletId}")
|
||||
|
||||
val nativeCurrencyStatus = getNativeCurrencyStatus(userWallet, network, userCurrenciesStatuses)
|
||||
val userCurrenciesStatuses = accountStatusList.flattenCurrencies()
|
||||
|
||||
val nativeCurrencyStatus = accountStatusList.getCoinStatus(network).getOrElse {
|
||||
raiseIllegalStateError("No native currency found: ${network.id}")
|
||||
}
|
||||
|
||||
if (!currencyChecksRepository.isNetworkSupportedForGaslessTx(network)) {
|
||||
return@either listOf(nativeCurrencyStatus)
|
||||
|
|
@ -58,21 +59,6 @@ class GetAvailableFeeTokensUseCase(
|
|||
}
|
||||
}
|
||||
|
||||
private suspend fun Raise<GetFeeError>.getNativeCurrencyStatus(
|
||||
userWallet: UserWallet,
|
||||
network: Network,
|
||||
userCurrenciesStatuses: List<CryptoCurrencyStatus>,
|
||||
): CryptoCurrencyStatus {
|
||||
val nativeCurrency = currenciesRepository.getNetworkCoin(
|
||||
userWalletId = userWallet.walletId,
|
||||
networkId = network.id,
|
||||
derivationPath = network.derivationPath,
|
||||
)
|
||||
return userCurrenciesStatuses.find {
|
||||
it.currency.id == nativeCurrency.id
|
||||
} ?: raiseIllegalStateError("no native currency found")
|
||||
}
|
||||
|
||||
private suspend fun getGaslessTokens(
|
||||
network: Network,
|
||||
userCurrenciesStatuses: List<CryptoCurrencyStatus>,
|
||||
|
|
|
|||
|
|
@ -9,13 +9,14 @@ import com.tangem.blockchain.blockchains.ethereum.EthereumWalletManager
|
|||
import com.tangem.blockchain.common.TransactionData
|
||||
import com.tangem.blockchain.common.transaction.Fee
|
||||
import com.tangem.blockchain.common.transaction.TransactionFee
|
||||
import com.tangem.domain.account.models.AccountStatusList
|
||||
import com.tangem.domain.account.status.supplier.SingleAccountStatusListSupplier
|
||||
import com.tangem.domain.account.status.utils.CryptoCurrencyStatusOperations.getCoinStatus
|
||||
import com.tangem.domain.demo.models.DemoConfig
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.tokens.GetMultiCryptoCurrencyStatusUseCase
|
||||
import com.tangem.domain.tokens.repository.CurrenciesRepository
|
||||
import com.tangem.domain.tokens.repository.CurrencyChecksRepository
|
||||
import com.tangem.domain.transaction.GaslessTransactionRepository
|
||||
import com.tangem.domain.transaction.error.GetFeeError
|
||||
|
|
@ -31,8 +32,7 @@ class GetFeeForGaslessUseCase(
|
|||
private val walletManagersFacade: WalletManagersFacade,
|
||||
private val demoConfig: DemoConfig,
|
||||
private val gaslessTransactionRepository: GaslessTransactionRepository,
|
||||
private val currenciesRepository: CurrenciesRepository,
|
||||
private val getMultiCryptoCurrencyStatusUseCase: GetMultiCryptoCurrencyStatusUseCase,
|
||||
private val singleAccountStatusListSupplier: SingleAccountStatusListSupplier,
|
||||
private val getFeeUseCase: GetFeeUseCase,
|
||||
private val currencyChecksRepository: CurrencyChecksRepository,
|
||||
) {
|
||||
|
|
@ -51,11 +51,12 @@ class GetFeeForGaslessUseCase(
|
|||
return either {
|
||||
catch(
|
||||
block = {
|
||||
val nativeCurrency = currenciesRepository.getNetworkCoin(
|
||||
userWalletId = userWallet.walletId,
|
||||
networkId = network.id,
|
||||
derivationPath = network.derivationPath,
|
||||
)
|
||||
val accountStatusList = singleAccountStatusListSupplier.getSyncOrNull(userWallet.walletId)
|
||||
?: raiseIllegalStateError("AccountStatusList is null for ${userWallet.walletId}")
|
||||
|
||||
val nativeCurrencyStatus = accountStatusList.getCoinStatus(network).getOrElse {
|
||||
raiseIllegalStateError("No native currency found: ${network.id}")
|
||||
}
|
||||
|
||||
if (!currencyChecksRepository.isNetworkSupportedForGaslessTx(network)) {
|
||||
getFeeUseCase.invoke(userWallet, network, transactionData).fold(
|
||||
|
|
@ -63,7 +64,7 @@ class GetFeeForGaslessUseCase(
|
|||
ifRight = { fee ->
|
||||
return@either TransactionFeeExtended(
|
||||
transactionFee = fee,
|
||||
feeTokenId = nativeCurrency.id,
|
||||
feeTokenId = nativeCurrencyStatus.currency.id,
|
||||
)
|
||||
},
|
||||
)
|
||||
|
|
@ -79,9 +80,9 @@ class GetFeeForGaslessUseCase(
|
|||
).bind()
|
||||
|
||||
selectFeePaymentStrategy(
|
||||
userWallet = userWallet,
|
||||
accountStatusList = accountStatusList,
|
||||
walletManager = walletManager,
|
||||
nativeCurrency = nativeCurrency,
|
||||
nativeCurrencyStatus = nativeCurrencyStatus,
|
||||
network = network,
|
||||
initialFee = initialFee,
|
||||
)
|
||||
|
|
@ -108,25 +109,17 @@ class GetFeeForGaslessUseCase(
|
|||
}
|
||||
|
||||
private suspend fun Raise<GetFeeError>.selectFeePaymentStrategy(
|
||||
userWallet: UserWallet,
|
||||
accountStatusList: AccountStatusList,
|
||||
walletManager: EthereumWalletManager,
|
||||
nativeCurrency: CryptoCurrency,
|
||||
nativeCurrencyStatus: CryptoCurrencyStatus,
|
||||
network: Network,
|
||||
initialFee: TransactionFee,
|
||||
): TransactionFeeExtended {
|
||||
val feeValue = initialFee.normal.amount.value ?: raise(GetFeeError.UnknownError)
|
||||
|
||||
val userCurrenciesStatuses = getMultiCryptoCurrencyStatusUseCase.invokeMultiWalletSync(
|
||||
userWallet.walletId,
|
||||
).getOrNull() ?: raiseIllegalStateError("currencies list is null for userWalletId=${userWallet.walletId}")
|
||||
|
||||
val networkCurrenciesStatuses = userCurrenciesStatuses.filter {
|
||||
it.currency.network.id == network.id
|
||||
}
|
||||
|
||||
val nativeCurrencyStatus = networkCurrenciesStatuses.find {
|
||||
it.currency.id == nativeCurrency.id
|
||||
} ?: raiseIllegalStateError("native currency not found for network ${network.id}")
|
||||
val networkCurrenciesStatuses = accountStatusList
|
||||
.flattenCurrencies()
|
||||
.filter { it.currency.network.id == network.id }
|
||||
|
||||
val nativeBalance = nativeCurrencyStatus.value.amount ?: BigDecimal.ZERO
|
||||
val nativeCoinSelectedResult =
|
||||
|
|
|
|||
|
|
@ -1,18 +1,20 @@
|
|||
package com.tangem.domain.transaction.usecase.gasless
|
||||
|
||||
import arrow.core.Either
|
||||
import arrow.core.getOrElse
|
||||
import arrow.core.raise.Raise
|
||||
import arrow.core.raise.catch
|
||||
import arrow.core.raise.either
|
||||
import com.tangem.blockchain.blockchains.ethereum.EthereumWalletManager
|
||||
import com.tangem.blockchain.common.TransactionData
|
||||
import com.tangem.blockchain.common.transaction.Fee
|
||||
import com.tangem.domain.account.status.supplier.SingleAccountStatusListSupplier
|
||||
import com.tangem.domain.account.status.utils.CryptoCurrencyStatusOperations.getCoinStatus
|
||||
import com.tangem.domain.account.status.utils.CryptoCurrencyStatusOperations.getCryptoCurrencyStatus
|
||||
import com.tangem.domain.demo.models.DemoConfig
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.tokens.GetMultiCryptoCurrencyStatusUseCase
|
||||
import com.tangem.domain.tokens.repository.CurrenciesRepository
|
||||
import com.tangem.domain.tokens.repository.CurrencyChecksRepository
|
||||
import com.tangem.domain.transaction.GaslessTransactionRepository
|
||||
import com.tangem.domain.transaction.error.GetFeeError
|
||||
|
|
@ -25,8 +27,7 @@ class GetFeeForTokenUseCase(
|
|||
private val gaslessTransactionRepository: GaslessTransactionRepository,
|
||||
private val walletManagersFacade: WalletManagersFacade,
|
||||
private val demoConfig: DemoConfig,
|
||||
private val currenciesRepository: CurrenciesRepository,
|
||||
private val getMultiCryptoCurrencyStatusUseCase: GetMultiCryptoCurrencyStatusUseCase,
|
||||
private val singleAccountStatusListSupplier: SingleAccountStatusListSupplier,
|
||||
private val currencyChecksRepository: CurrencyChecksRepository,
|
||||
) {
|
||||
|
||||
|
|
@ -62,25 +63,16 @@ class GetFeeForTokenUseCase(
|
|||
error = "only Fee.Ethereum supported, but was different",
|
||||
)
|
||||
|
||||
val nativeCurrency = currenciesRepository.getNetworkCoin(
|
||||
userWalletId = userWallet.walletId,
|
||||
networkId = token.network.id,
|
||||
derivationPath = token.network.derivationPath,
|
||||
)
|
||||
val accountStatusList = singleAccountStatusListSupplier.getSyncOrNull(userWallet.walletId)
|
||||
?: raiseIllegalStateError("AccountStatusList is null for ${userWallet.walletId}")
|
||||
|
||||
val userCurrenciesStatusesByNetwork = getMultiCryptoCurrencyStatusUseCase.invokeMultiWalletSync(
|
||||
userWallet.walletId,
|
||||
).getOrNull()?.filter {
|
||||
it.currency.network.id == token.network.id
|
||||
} ?: raiseIllegalStateError("currencies list is null for userWalletId=${userWallet.walletId}")
|
||||
val nativeCurrencyStatus = accountStatusList.getCoinStatus(token.network).getOrElse {
|
||||
raiseIllegalStateError("Native currency not found for network ${token.network.id}")
|
||||
}
|
||||
|
||||
val nativeCurrencyStatus = userCurrenciesStatusesByNetwork.find {
|
||||
it.currency.id == nativeCurrency.id
|
||||
} ?: raiseIllegalStateError("native currency not found for network ${token.network.id}")
|
||||
|
||||
val tokenCurrencyStatus = userCurrenciesStatusesByNetwork.find {
|
||||
it.currency.id == token.id
|
||||
} ?: raiseIllegalStateError("token currency not found for network ${token.network.id}")
|
||||
val tokenCurrencyStatus = accountStatusList.getCryptoCurrencyStatus(currency = token).getOrElse {
|
||||
raiseIllegalStateError("Token currency not found for network ${token.network.id}")
|
||||
}
|
||||
|
||||
tokenFeeCalculator.calculateTokenFee(
|
||||
walletManager = walletManager,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue