Updated on 2026-08-14
This commit is contained in:
parent
5cc1aa7ce8
commit
c9917f1c05
8 changed files with 128 additions and 81 deletions
|
|
@ -6,6 +6,7 @@ import com.tangem.blockchain.common.TransactionSender
|
|||
import com.tangem.blockchain.common.TransactionSigner
|
||||
import com.tangem.blockchain.common.WalletManager
|
||||
import com.tangem.blockchain.common.toBlockchainSdkError
|
||||
import com.tangem.blockchain.common.transaction.TransactionFee
|
||||
import com.tangem.blockchain.extensions.Result
|
||||
import com.tangem.blockchain.extensions.SimpleResult
|
||||
import com.tangem.common.CompletionResult
|
||||
|
|
@ -84,14 +85,14 @@ object DemoHelper {
|
|||
|
||||
class DemoTransactionSender(private val walletManager: WalletManager) : TransactionSender {
|
||||
|
||||
override suspend fun getFee(amount: Amount, destination: String): Result<List<Amount>> {
|
||||
override suspend fun getFee(amount: Amount, destination: String): Result<TransactionFee> {
|
||||
val blockchain = walletManager.wallet.blockchain
|
||||
return Result.Success(
|
||||
listOf(
|
||||
Amount(0.0001.toBigDecimal(), blockchain),
|
||||
Amount(0.0002.toBigDecimal(), blockchain),
|
||||
Amount(0.0003.toBigDecimal(), blockchain),
|
||||
),
|
||||
TransactionFee.Choosable(
|
||||
minimum = Amount(0.0001.toBigDecimal(), blockchain),
|
||||
normal = Amount(0.0002.toBigDecimal(), blockchain),
|
||||
priority = Amount(0.0003.toBigDecimal(), blockchain)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import com.tangem.blockchain.common.Blockchain
|
|||
import com.tangem.blockchain.common.BlockchainSdkError
|
||||
import com.tangem.blockchain.common.TransactionSigner
|
||||
import com.tangem.blockchain.common.WalletManager
|
||||
import com.tangem.blockchain.common.transaction.TransactionFee
|
||||
import com.tangem.blockchain.extensions.Result
|
||||
import com.tangem.blockchain.extensions.SimpleResult
|
||||
import com.tangem.blockchain.extensions.successOr
|
||||
|
|
@ -205,13 +206,16 @@ class GnosisRegistrator(
|
|||
}
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
private fun Result<List<Amount>>.extractFeeAmount(): Result<Amount> {
|
||||
private fun Result<TransactionFee>.extractFeeAmount(): Result<Amount> {
|
||||
return when (this) {
|
||||
is Result.Success -> {
|
||||
if (this.data.size != 3) {
|
||||
Result.Failure(BlockchainSdkError.FailedToLoadFee)
|
||||
} else {
|
||||
Result.Success(this.data[1])
|
||||
when(data) {
|
||||
is TransactionFee.Single -> {
|
||||
Result.Failure(BlockchainSdkError.FailedToLoadFee)
|
||||
}
|
||||
is TransactionFee.Choosable -> {
|
||||
Result.Success((data as TransactionFee.Choosable).normal)
|
||||
}
|
||||
}
|
||||
}
|
||||
is Result.Failure -> this
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import com.tangem.Message
|
|||
import com.tangem.blockchain.common.Amount
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.WalletManager
|
||||
import com.tangem.blockchain.common.transaction.TransactionFee
|
||||
import com.tangem.common.core.TangemSdkError
|
||||
import com.tangem.tap.common.redux.ErrorAction
|
||||
import com.tangem.tap.common.redux.StateDialog
|
||||
|
|
@ -127,7 +128,7 @@ sealed class FeeAction : SendScreenAction {
|
|||
|
||||
object RequestFee : FeeAction()
|
||||
sealed class FeeCalculation : FeeAction() {
|
||||
data class SetFeeResult(val fee: List<Amount>) : FeeCalculation()
|
||||
data class SetFeeResult(val fee: TransactionFee) : FeeCalculation()
|
||||
object ClearResult : FeeCalculation()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.tangem.tap.features.send.redux.middlewares
|
|||
import com.tangem.blockchain.common.Amount
|
||||
import com.tangem.blockchain.common.BlockchainSdkError
|
||||
import com.tangem.blockchain.common.TransactionSender
|
||||
import com.tangem.blockchain.common.transaction.TransactionFee
|
||||
import com.tangem.blockchain.extensions.Result
|
||||
import com.tangem.common.extensions.isZero
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
|
|
@ -53,15 +54,18 @@ class RequestFeeMiddleware {
|
|||
val result = feeResult.data
|
||||
// val result = FeeMock.getFee(walletManager.wallet.blockchain)
|
||||
dispatch(FeeAction.FeeCalculation.SetFeeResult(result))
|
||||
if (result.size == 1) {
|
||||
val fee = result[0].value ?: BigDecimal.ZERO
|
||||
if (fee.isZero()) {
|
||||
dispatch(FeeAction.ChangeLayoutVisibility(main = false))
|
||||
} else {
|
||||
dispatch(FeeAction.ChangeLayoutVisibility(main = true, chipGroup = false))
|
||||
when(result) {
|
||||
is TransactionFee.Single -> {
|
||||
val fee = result.value.value ?: BigDecimal.ZERO
|
||||
if (fee.isZero()) {
|
||||
dispatch(FeeAction.ChangeLayoutVisibility(main = false))
|
||||
} else {
|
||||
dispatch(FeeAction.ChangeLayoutVisibility(main = true, chipGroup = false))
|
||||
}
|
||||
}
|
||||
is TransactionFee.Choosable -> {
|
||||
dispatch(FeeAction.ChangeLayoutVisibility(main = true, chipGroup = true))
|
||||
}
|
||||
} else {
|
||||
dispatch(FeeAction.ChangeLayoutVisibility(main = true, chipGroup = true))
|
||||
}
|
||||
}
|
||||
is Result.Failure -> {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.tap.features.send.redux.reducers
|
||||
|
||||
import com.tangem.blockchain.common.Amount
|
||||
import com.tangem.blockchain.common.transaction.TransactionFee
|
||||
import com.tangem.tap.features.send.redux.FeeAction
|
||||
import com.tangem.tap.features.send.redux.FeeActionUi
|
||||
import com.tangem.tap.features.send.redux.SendScreenAction
|
||||
|
|
@ -13,6 +14,7 @@ import com.tangem.tap.features.wallet.redux.ProgressState
|
|||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
class FeeReducer : SendInternalReducer {
|
||||
|
||||
override fun handle(action: SendScreenAction, sendState: SendState): SendState = when (action) {
|
||||
is FeeActionUi -> handleUiAction(action, sendState, sendState.feeState)
|
||||
is FeeAction -> handleAction(action, sendState, sendState.feeState)
|
||||
|
|
@ -25,11 +27,13 @@ class FeeReducer : SendInternalReducer {
|
|||
state.copy(controlsLayoutIsVisible = !state.controlsLayoutIsVisible)
|
||||
}
|
||||
is FeeActionUi.ChangeSelectedFee -> {
|
||||
val currentFee = createValueOfFeeAmount(action.feeType, state.feeList)
|
||||
state.copy(
|
||||
selectedFeeType = action.feeType,
|
||||
currentFee = currentFee,
|
||||
)
|
||||
state.feeList?.let {
|
||||
val currentFee = createValueOfFeeAmount(action.feeType, it)
|
||||
state.copy(
|
||||
selectedFeeType = action.feeType,
|
||||
currentFee = currentFee,
|
||||
)
|
||||
} ?: state
|
||||
}
|
||||
is FeeActionUi.ChangeIncludeFee -> state.copy(feeIsIncluded = action.isIncluded)
|
||||
}
|
||||
|
|
@ -51,26 +55,29 @@ class FeeReducer : SendInternalReducer {
|
|||
}
|
||||
is FeeAction.FeeCalculation.SetFeeResult -> {
|
||||
val fees = action.fee
|
||||
if (fees.size == 1) {
|
||||
val feeType = FeeType.SINGLE
|
||||
val currentFee = createValueOfFeeAmount(feeType, fees)
|
||||
when (fees) {
|
||||
is TransactionFee.Single -> {
|
||||
val feeType = FeeType.SINGLE
|
||||
val currentFee = createValueOfFeeAmount(feeType, fees)
|
||||
|
||||
state.copy(
|
||||
selectedFeeType = feeType,
|
||||
feeList = fees,
|
||||
currentFee = currentFee,
|
||||
feeIsApproximate = isFeeApproximate(sendState),
|
||||
)
|
||||
} else {
|
||||
val feeType = getCurrentFeeType(state)
|
||||
val currentFee = createValueOfFeeAmount(feeType, fees)
|
||||
state.copy(
|
||||
selectedFeeType = feeType,
|
||||
feeList = fees,
|
||||
currentFee = currentFee,
|
||||
feeIsApproximate = isFeeApproximate(sendState),
|
||||
)
|
||||
}
|
||||
is TransactionFee.Choosable -> {
|
||||
val feeType = getCurrentFeeType(state)
|
||||
val currentFee = createValueOfFeeAmount(feeType, fees)
|
||||
|
||||
state.copy(
|
||||
selectedFeeType = feeType,
|
||||
feeList = fees,
|
||||
currentFee = currentFee,
|
||||
feeIsApproximate = isFeeApproximate(sendState),
|
||||
)
|
||||
state.copy(
|
||||
selectedFeeType = feeType,
|
||||
feeList = fees,
|
||||
currentFee = currentFee,
|
||||
feeIsApproximate = isFeeApproximate(sendState),
|
||||
)
|
||||
}
|
||||
}.copy(
|
||||
progressState = ProgressState.Done,
|
||||
)
|
||||
|
|
@ -87,17 +94,18 @@ class FeeReducer : SendInternalReducer {
|
|||
return updateLastState(sendState.copy(feeState = result), result)
|
||||
}
|
||||
|
||||
private fun createValueOfFeeAmount(feeType: FeeType, list: List<Amount>?): Amount? {
|
||||
if (list == null || list.isEmpty()) return null
|
||||
|
||||
return if (list.size == 1) {
|
||||
list[0]
|
||||
} else {
|
||||
when (feeType) {
|
||||
FeeType.SINGLE -> list[1]
|
||||
FeeType.LOW -> list[0]
|
||||
FeeType.NORMAL -> list[1]
|
||||
FeeType.PRIORITY -> list[2]
|
||||
private fun createValueOfFeeAmount(feeType: FeeType, transactionFee: TransactionFee): Amount {
|
||||
return when (transactionFee) {
|
||||
is TransactionFee.Single -> {
|
||||
transactionFee.value
|
||||
}
|
||||
is TransactionFee.Choosable -> {
|
||||
when (feeType) {
|
||||
FeeType.SINGLE -> transactionFee.normal
|
||||
FeeType.LOW -> transactionFee.minimum
|
||||
FeeType.NORMAL -> transactionFee.normal
|
||||
FeeType.PRIORITY -> transactionFee.priority
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.tap.features.send.redux.states
|
||||
|
||||
import com.tangem.blockchain.common.Amount
|
||||
import com.tangem.blockchain.common.transaction.TransactionFee
|
||||
import com.tangem.tap.features.wallet.redux.ProgressState
|
||||
import java.math.BigDecimal
|
||||
|
||||
|
|
@ -13,7 +14,7 @@ enum class FeeType {
|
|||
|
||||
data class FeeState(
|
||||
val selectedFeeType: FeeType = FeeType.NORMAL,
|
||||
val feeList: List<Amount>? = null,
|
||||
val feeList: TransactionFee? = null,
|
||||
val currentFee: Amount? = null,
|
||||
val feeIsIncluded: Boolean = false,
|
||||
val feeIsApproximate: Boolean = false,
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ class CurrencyExchangeManager(
|
|||
return when (action) {
|
||||
Action.Buy -> buyService
|
||||
Action.Sell -> sellService
|
||||
} as ExchangeUrlBuilder
|
||||
}
|
||||
}
|
||||
|
||||
enum class Action { Buy, Sell }
|
||||
|
|
@ -96,12 +96,11 @@ suspend fun CurrencyExchangeManager.buyErc20TestnetTokens(
|
|||
val amountToSend = Amount(walletManager.wallet.blockchain)
|
||||
val destinationAddress = token.contractAddress
|
||||
|
||||
val feeResult =
|
||||
walletManager.getFee(
|
||||
val feeResult = walletManager.getFee(
|
||||
amountToSend,
|
||||
destinationAddress,
|
||||
) as? Result.Success ?: return
|
||||
val fee = feeResult.data[0]
|
||||
val fee = feeResult.data.minimum
|
||||
|
||||
val coinValue = walletManager.wallet.amounts[AmountType.Coin]?.value ?: BigDecimal.ZERO
|
||||
if (coinValue < fee.value) return
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import com.tangem.blockchain.blockchains.ethereum.EthereumTransactionExtras
|
|||
import com.tangem.blockchain.blockchains.ethereum.EthereumWalletManager
|
||||
import com.tangem.blockchain.blockchains.optimism.OptimismWalletManager
|
||||
import com.tangem.blockchain.common.*
|
||||
import com.tangem.blockchain.common.transaction.TransactionFee
|
||||
import com.tangem.blockchain.extensions.Result
|
||||
import com.tangem.blockchain.extensions.SimpleResult
|
||||
import com.tangem.blockchain.extensions.isNetworkError
|
||||
|
|
@ -197,24 +198,37 @@ class TransactionManagerImpl(
|
|||
return when (fee) {
|
||||
is Result.Success -> {
|
||||
// for not EVM blockchains set gasLimit ZERO for now
|
||||
val firstFee = fee.data.firstOrNull() ?: error("no fee found")
|
||||
val minFee = ProxyFee(
|
||||
gasLimit = BigInteger.ZERO,
|
||||
fee = convertToProxyAmount(amount = firstFee),
|
||||
)
|
||||
val normalFee = ProxyFee(
|
||||
gasLimit = BigInteger.ZERO,
|
||||
fee = convertToProxyAmount(fee.data.getOrNull(index = 1) ?: firstFee),
|
||||
)
|
||||
val priorityFee = ProxyFee(
|
||||
gasLimit = BigInteger.ZERO,
|
||||
fee = convertToProxyAmount(fee.data.getOrNull(index = 2) ?: firstFee),
|
||||
)
|
||||
ProxyFees(
|
||||
minFee = minFee,
|
||||
normalFee = normalFee,
|
||||
priorityFee = priorityFee,
|
||||
)
|
||||
when (fee.data) {
|
||||
is TransactionFee.Single -> {
|
||||
val singleFee = ProxyFee(
|
||||
gasLimit = BigInteger.ZERO,
|
||||
fee = convertToProxyAmount(amount = (fee.data as TransactionFee.Single).value),
|
||||
)
|
||||
ProxyFees(
|
||||
minFee = singleFee,
|
||||
normalFee = singleFee,
|
||||
priorityFee = singleFee
|
||||
)
|
||||
}
|
||||
is TransactionFee.Choosable -> {
|
||||
val setOfThree = fee.data as TransactionFee.Choosable
|
||||
ProxyFees(
|
||||
minFee = ProxyFee(
|
||||
gasLimit = BigInteger.ZERO,
|
||||
fee = convertToProxyAmount(amount = setOfThree.minimum),
|
||||
),
|
||||
normalFee = ProxyFee(
|
||||
gasLimit = BigInteger.ZERO,
|
||||
fee = convertToProxyAmount(amount = setOfThree.normal),
|
||||
),
|
||||
priorityFee = ProxyFee(
|
||||
gasLimit = BigInteger.ZERO,
|
||||
fee = convertToProxyAmount(amount = setOfThree.priority),
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
is Result.Failure -> {
|
||||
error(fee.error.message ?: fee.error.customMessage)
|
||||
|
|
@ -263,18 +277,33 @@ class TransactionManagerImpl(
|
|||
}
|
||||
return when (fee) {
|
||||
is Result.Success -> {
|
||||
val minFee = fee.data.firstOrNull() ?: error("no fee found")
|
||||
val choosableFee = fee.data
|
||||
ProxyFees(
|
||||
minFee = ProxyFee(
|
||||
gasLimit = walletManager.gasLimit ?: BigInteger.ZERO,
|
||||
fee = convertToProxyAmount(choosableFee.minimum),
|
||||
),
|
||||
normalFee = ProxyFee(
|
||||
gasLimit = BigInteger.ZERO,
|
||||
fee = convertToProxyAmount(amount = choosableFee.normal),
|
||||
),
|
||||
priorityFee = ProxyFee(
|
||||
gasLimit = BigInteger.ZERO,
|
||||
fee = convertToProxyAmount(amount = choosableFee.priority),
|
||||
)
|
||||
)
|
||||
|
||||
val minProxyFee = ProxyFee(
|
||||
gasLimit = walletManager.gasLimit ?: BigInteger.ZERO,
|
||||
fee = convertToProxyAmount(minFee),
|
||||
fee = convertToProxyAmount(fee.data.minimum),
|
||||
)
|
||||
val normalProxyFee = ProxyFee(
|
||||
gasLimit = walletManager.gasLimit ?: BigInteger.ZERO,
|
||||
fee = convertToProxyAmount(fee.data.getOrNull(index = 1) ?: minFee),
|
||||
fee = convertToProxyAmount(fee.data.normal),
|
||||
)
|
||||
val priorityProxyFee = ProxyFee(
|
||||
gasLimit = walletManager.gasLimit ?: BigInteger.ZERO,
|
||||
fee = convertToProxyAmount(fee.data.lastOrNull() ?: minFee),
|
||||
fee = convertToProxyAmount(fee.data.priority),
|
||||
)
|
||||
ProxyFees(
|
||||
minFee = minProxyFee,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue