Updated on 2026-08-14

This commit is contained in:
Tangem 2022-05-28 16:12:25 +03:00
parent 8312c85fa6
commit 20755c42bb
7 changed files with 52 additions and 74 deletions

View file

@ -1,11 +0,0 @@
package com.tangem.tap.domain.extensions
import com.tangem.blockchain.common.Amount
import com.tangem.blockchain.common.AmountType
import com.tangem.blockchain.extensions.isAboveZero
fun Map<AmountType, Amount>.toSendableAmounts(): List<Amount> {
return this.toList().unzip().second
.filter { it.type != AmountType.Reserve }
.filter { it.isAboveZero() }
}

View file

@ -7,8 +7,7 @@ import com.tangem.domain.common.isTangemTwin
import com.tangem.tap.common.redux.AppState import com.tangem.tap.common.redux.AppState
import com.tangem.tap.domain.extensions.isWalletDataSupported import com.tangem.tap.domain.extensions.isWalletDataSupported
import com.tangem.tap.domain.extensions.signedHashesCount import com.tangem.tap.domain.extensions.signedHashesCount
import com.tangem.tap.domain.extensions.toSendableAmounts import com.tangem.tap.features.wallet.models.hasSendableAmountsOrPendingTransactions
import com.tangem.tap.features.wallet.models.hasPendingTransactions
import org.rekotlin.Action import org.rekotlin.Action
import java.util.* import java.util.*
@ -62,9 +61,7 @@ private fun handleEraseWallet(
(card?.isWalletDataSupported == true && (card?.isWalletDataSupported == true &&
(!state.scanResponse.isTangemNote() && !state.scanResponse.supportsBackup())) (!state.scanResponse.isTangemNote() && !state.scanResponse.supportsBackup()))
val notEmpty = state.wallets.any { val notEmpty = state.wallets.any { it.hasSendableAmountsOrPendingTransactions() }
it.hasPendingTransactions() || it.amounts.toSendableAmounts().isNotEmpty()
}
val eraseWalletState = when { val eraseWalletState = when {
notAllowedByCard -> EraseWalletState.NotAllowedByCard notAllowedByCard -> EraseWalletState.NotAllowedByCard
notEmpty -> EraseWalletState.NotEmpty notEmpty -> EraseWalletState.NotEmpty

View file

@ -1,11 +1,8 @@
package com.tangem.tap.features.wallet.models package com.tangem.tap.features.wallet.models
import com.tangem.blockchain.common.Token import com.tangem.blockchain.common.*
import com.tangem.blockchain.common.TransactionData import com.tangem.blockchain.extensions.isAboveZero
import com.tangem.blockchain.common.TransactionStatus
import com.tangem.blockchain.common.Wallet
import com.tangem.tap.common.extensions.toFormattedString import com.tangem.tap.common.extensions.toFormattedString
import com.tangem.tap.domain.extensions.toSendableAmounts
import java.math.BigDecimal import java.math.BigDecimal
data class PendingTransaction( data class PendingTransaction(
@ -60,22 +57,45 @@ fun TransactionData.toPendingTransactionForToken(token: Token, walletAddress: St
return this.toPendingTransaction(walletAddress) return this.toPendingTransaction(walletAddress)
} }
fun List<TransactionData>.toPendingTransactionsForToken(token: Token, walletAddress: String): List<PendingTransaction> {
return this.mapNotNull { it.toPendingTransactionForToken(token, walletAddress) }
}
fun Wallet.getPendingTransactions(type: PendingTransactionType? = null): List<PendingTransaction> { fun Wallet.getPendingTransactions(type: PendingTransactionType? = null): List<PendingTransaction> {
val txs = recentTransactions.toPendingTransactions(address) val txs = recentTransactions.toPendingTransactions(address)
return when(type) { return when (type) {
null -> txs null -> txs
else -> txs.filter { it.type == type } else -> txs.filter { it.type == type }
} }
} }
fun Wallet.getPendingTransactions(token: Token): List<PendingTransaction> {
return recentTransactions.mapNotNull { it.toPendingTransactionForToken(token, address) }
}
fun Wallet.hasPendingTransactions(): Boolean { fun Wallet.hasPendingTransactions(): Boolean {
return getPendingTransactions().isNotEmpty() return getPendingTransactions().isNotEmpty()
} }
fun Wallet.hasPendingTransactions(token: Token): Boolean {
return getPendingTransactions(token).isNotEmpty()
}
fun Wallet.getSendableAmounts(): List<Amount> {
return amounts.values
.filter { it.type != AmountType.Reserve }
.filter { it.isAboveZero() }
}
fun Wallet.hasSendableAmounts(): Boolean {
return getSendableAmounts().isNotEmpty()
}
fun Wallet.hasSendableAmountsOrPendingTransactions(): Boolean { fun Wallet.hasSendableAmountsOrPendingTransactions(): Boolean {
return hasPendingTransactions() || amounts.toSendableAmounts().isNotEmpty() return hasPendingTransactions() || hasSendableAmounts()
}
fun Wallet.isSendableAmount(type: AmountType): Boolean {
return amounts[type]?.isAboveZero() == true
}
fun Wallet.isSendableAmount(token: Token): Boolean {
return isSendableAmount(AmountType.Token(token))
} }

View file

@ -1,15 +1,8 @@
package com.tangem.tap.features.wallet.redux package com.tangem.tap.features.wallet.redux
import android.graphics.Bitmap import android.graphics.Bitmap
import com.tangem.blockchain.common.Amount import com.tangem.blockchain.common.*
import com.tangem.blockchain.common.AmountType
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.DerivationStyle
import com.tangem.blockchain.common.Token
import com.tangem.blockchain.common.Wallet
import com.tangem.blockchain.common.WalletManager
import com.tangem.blockchain.common.address.AddressType import com.tangem.blockchain.common.address.AddressType
import com.tangem.blockchain.extensions.isAboveZero
import com.tangem.common.extensions.isZero import com.tangem.common.extensions.isZero
import com.tangem.domain.common.extensions.canHandleToken import com.tangem.domain.common.extensions.canHandleToken
import com.tangem.domain.common.extensions.toCoinId import com.tangem.domain.common.extensions.toCoinId
@ -22,22 +15,16 @@ import com.tangem.tap.common.toggleWidget.WidgetState
import com.tangem.tap.domain.configurable.warningMessage.WarningMessage import com.tangem.tap.domain.configurable.warningMessage.WarningMessage
import com.tangem.tap.domain.extensions.buyIsAllowed import com.tangem.tap.domain.extensions.buyIsAllowed
import com.tangem.tap.domain.extensions.sellIsAllowed import com.tangem.tap.domain.extensions.sellIsAllowed
import com.tangem.tap.domain.extensions.toSendableAmounts
import com.tangem.tap.domain.tokens.BlockchainNetwork import com.tangem.tap.domain.tokens.BlockchainNetwork
import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsState import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsState
import com.tangem.tap.features.tokens.redux.TokenWithBlockchain import com.tangem.tap.features.tokens.redux.TokenWithBlockchain
import com.tangem.tap.features.wallet.models.PendingTransaction import com.tangem.tap.features.wallet.models.*
import com.tangem.tap.features.wallet.models.TotalBalance
import com.tangem.tap.features.wallet.models.WalletRent
import com.tangem.tap.features.wallet.models.WalletWarning
import com.tangem.tap.features.wallet.models.toPendingTransactions
import com.tangem.tap.features.wallet.models.toPendingTransactionsForToken
import com.tangem.tap.features.wallet.ui.BalanceStatus import com.tangem.tap.features.wallet.ui.BalanceStatus
import com.tangem.tap.features.wallet.ui.BalanceWidgetData import com.tangem.tap.features.wallet.ui.BalanceWidgetData
import com.tangem.tap.network.exchangeServices.CurrencyExchangeManager import com.tangem.tap.network.exchangeServices.CurrencyExchangeManager
import com.tangem.tap.store import com.tangem.tap.store
import java.math.BigDecimal
import org.rekotlin.StateType import org.rekotlin.StateType
import java.math.BigDecimal
import kotlin.properties.ReadOnlyProperty import kotlin.properties.ReadOnlyProperty
data class WalletState( data class WalletState(
@ -151,16 +138,13 @@ data class WalletState(
val wallet = walletManager.wallet val wallet = walletManager.wallet
if (walletData.currency is Currency.Blockchain) { return when (walletData.currency) {
return wallet.recentTransactions.toPendingTransactions(wallet.address).isEmpty() && is Currency.Blockchain -> !wallet.hasPendingTransactions() && !wallet.hasSendableAmounts()
wallet.amounts.toSendableAmounts().isEmpty() is Currency.Token -> {
} else if (walletData.currency is Currency.Token) ( val token = walletData.currency.token
return wallet.recentTransactions.toPendingTransactionsForToken( !wallet.hasPendingTransactions(token) && !wallet.isSendableAmount(token)
walletData.currency.token, wallet.address }
).isEmpty() }
&& wallet.amounts[AmountType.Token(token = walletData.currency.token)]
?.isAboveZero() != true
)
} }
return false return false
} }

View file

@ -15,19 +15,12 @@ import com.tangem.domain.common.extensions.withMainContext
import com.tangem.operations.attestation.Attestation import com.tangem.operations.attestation.Attestation
import com.tangem.operations.attestation.OnlineCardVerifier import com.tangem.operations.attestation.OnlineCardVerifier
import com.tangem.tap.common.analytics.Analytics import com.tangem.tap.common.analytics.Analytics
import com.tangem.tap.common.extensions.copyToClipboard import com.tangem.tap.common.extensions.*
import com.tangem.tap.common.extensions.dispatchDebugErrorNotification
import com.tangem.tap.common.extensions.dispatchDialogShow
import com.tangem.tap.common.extensions.dispatchOnMain
import com.tangem.tap.common.extensions.onCardScanned
import com.tangem.tap.common.extensions.shareText
import com.tangem.tap.common.extensions.stripZeroPlainString
import com.tangem.tap.common.redux.AppDialog import com.tangem.tap.common.redux.AppDialog
import com.tangem.tap.common.redux.AppState import com.tangem.tap.common.redux.AppState
import com.tangem.tap.common.redux.global.GlobalAction import com.tangem.tap.common.redux.global.GlobalAction
import com.tangem.tap.common.redux.navigation.AppScreen import com.tangem.tap.common.redux.navigation.AppScreen
import com.tangem.tap.common.redux.navigation.NavigationAction import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.domain.extensions.toSendableAmounts
import com.tangem.tap.domain.failedRates import com.tangem.tap.domain.failedRates
import com.tangem.tap.domain.loadedRates import com.tangem.tap.domain.loadedRates
import com.tangem.tap.features.demo.DemoHelper import com.tangem.tap.features.demo.DemoHelper
@ -35,17 +28,13 @@ import com.tangem.tap.features.home.redux.HomeAction
import com.tangem.tap.features.send.redux.PrepareSendScreen import com.tangem.tap.features.send.redux.PrepareSendScreen
import com.tangem.tap.features.wallet.models.PendingTransactionType import com.tangem.tap.features.wallet.models.PendingTransactionType
import com.tangem.tap.features.wallet.models.getPendingTransactions import com.tangem.tap.features.wallet.models.getPendingTransactions
import com.tangem.tap.features.wallet.redux.Currency import com.tangem.tap.features.wallet.models.getSendableAmounts
import com.tangem.tap.features.wallet.redux.WalletAction import com.tangem.tap.features.wallet.redux.*
import com.tangem.tap.features.wallet.redux.WalletData
import com.tangem.tap.features.wallet.redux.WalletState
import com.tangem.tap.features.wallet.redux.WalletStore
import com.tangem.tap.network.NetworkStateChanged import com.tangem.tap.network.NetworkStateChanged
import com.tangem.tap.preferencesStorage import com.tangem.tap.preferencesStorage
import com.tangem.tap.scope import com.tangem.tap.scope
import com.tangem.tap.store import com.tangem.tap.store
import com.tangem.tap.tangemSdkManager import com.tangem.tap.tangemSdkManager
import java.math.BigDecimal
import kotlinx.coroutines.async import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -53,6 +42,7 @@ import org.rekotlin.Action
import org.rekotlin.DispatchFunction import org.rekotlin.DispatchFunction
import org.rekotlin.Middleware import org.rekotlin.Middleware
import timber.log.Timber import timber.log.Timber
import java.math.BigDecimal
class WalletMiddleware { class WalletMiddleware {
private val tradeCryptoMiddleware = TradeCryptoMiddleware() private val tradeCryptoMiddleware = TradeCryptoMiddleware()
@ -266,7 +256,7 @@ class WalletMiddleware {
PrepareSendScreen(amount, selectedWalletData?.fiatRate, walletStore?.walletManager) PrepareSendScreen(amount, selectedWalletData?.fiatRate, walletStore?.walletManager)
} }
} else { } else {
val amounts = walletStore?.walletManager?.wallet?.amounts?.toSendableAmounts() val amounts = walletStore?.walletManager?.wallet?.getSendableAmounts()
if (currency != null && state.isMultiwalletAllowed) { if (currency != null && state.isMultiwalletAllowed) {
when (currency) { when (currency) {
is Currency.Blockchain -> { is Currency.Blockchain -> {

View file

@ -107,8 +107,7 @@ class MultiWalletReducer {
} }
val pendingTransactions = wallet.recentTransactions.toPendingTransactions(wallet.address) val pendingTransactions = wallet.recentTransactions.toPendingTransactions(wallet.address)
val sendButtonEnabled = val tokenSendButton = action.amount.value?.isZero() == false && pendingTransactions.isEmpty()
action.amount.value?.isZero() == false && pendingTransactions.isEmpty()
val tokenPendingTransactions = pendingTransactions val tokenPendingTransactions = pendingTransactions
.filter { it.currency == action.amount.currencySymbol } .filter { it.currency == action.amount.currencySymbol }
val tokenBalanceStatus = when { val tokenBalanceStatus = when {
@ -131,7 +130,7 @@ class MultiWalletReducer {
blockchainAmount = wallet.amounts[AmountType.Coin]?.value ?: BigDecimal.ZERO blockchainAmount = wallet.amounts[AmountType.Coin]?.value ?: BigDecimal.ZERO
), ),
pendingTransactions = pendingTransactions.removeUnknownTransactions(), pendingTransactions = pendingTransactions.removeUnknownTransactions(),
mainButton = WalletMainButton.SendButton(sendButtonEnabled), mainButton = WalletMainButton.SendButton(tokenSendButton),
currency = Currency.Token( currency = Currency.Token(
token = action.token, token = action.token,
blockchain = action.blockchain.blockchain, blockchain = action.blockchain.blockchain,

View file

@ -9,6 +9,7 @@ import com.tangem.tap.common.extensions.toFormattedCurrencyString
import com.tangem.tap.common.extensions.toFormattedFiatValue import com.tangem.tap.common.extensions.toFormattedFiatValue
import com.tangem.tap.domain.getFirstToken import com.tangem.tap.domain.getFirstToken
import com.tangem.tap.domain.tokens.BlockchainNetwork import com.tangem.tap.domain.tokens.BlockchainNetwork
import com.tangem.tap.features.wallet.models.getPendingTransactions
import com.tangem.tap.features.wallet.models.removeUnknownTransactions import com.tangem.tap.features.wallet.models.removeUnknownTransactions
import com.tangem.tap.features.wallet.models.toPendingTransactions import com.tangem.tap.features.wallet.models.toPendingTransactions
import com.tangem.tap.features.wallet.redux.* import com.tangem.tap.features.wallet.redux.*
@ -44,9 +45,7 @@ class OnWalletLoadedReducer {
wallet.blockchain.currency wallet.blockchain.currency
) )
val pendingTransactions = wallet.recentTransactions val pendingTransactions = wallet.getPendingTransactions()
.toPendingTransactions(wallet.address)
val coinSendButton = coinAmountValue?.isZero() == false && pendingTransactions.isEmpty() val coinSendButton = coinAmountValue?.isZero() == false && pendingTransactions.isEmpty()
val balanceStatus = if (pendingTransactions.isNotEmpty()) { val balanceStatus = if (pendingTransactions.isNotEmpty()) {
BalanceStatus.TransactionInProgress BalanceStatus.TransactionInProgress