Updated on 2026-08-14
This commit is contained in:
commit
467442724d
595 changed files with 7210 additions and 3334 deletions
|
|
@ -18,7 +18,7 @@ import dagger.assisted.AssistedFactory
|
|||
import dagger.assisted.AssistedInject
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import com.tangem.utils.logging.TangemLogger
|
||||
|
||||
@Suppress("ComplexCondition")
|
||||
internal class DefaultSellRedirectDeepLinkHandler @AssistedInject constructor(
|
||||
|
|
@ -40,13 +40,13 @@ internal class DefaultSellRedirectDeepLinkHandler @AssistedInject constructor(
|
|||
getSelectedWalletSyncUseCase()
|
||||
.fold(
|
||||
ifLeft = {
|
||||
Timber.e("Error on getting user wallet: $it")
|
||||
TangemLogger.e("Error on getting user wallet: $it")
|
||||
},
|
||||
ifRight = { userWallet ->
|
||||
if (currencyId.isNullOrEmpty() || transactionId.isNullOrEmpty() ||
|
||||
amount.isNullOrEmpty() || destinationAddress.isNullOrEmpty()
|
||||
) {
|
||||
Timber.e(
|
||||
TangemLogger.e(
|
||||
"""
|
||||
Invalid parameters for SELL deeplink
|
||||
|- Params: $queryParams
|
||||
|
|
@ -57,7 +57,7 @@ internal class DefaultSellRedirectDeepLinkHandler @AssistedInject constructor(
|
|||
|
||||
scope.launch {
|
||||
val cryptoCurrency = getCryptoCurrency(userWallet.walletId, currencyId).getOrElse {
|
||||
Timber.e("Error on getting cryptoCurrency: $currencyId")
|
||||
TangemLogger.e("Error on getting cryptoCurrency: $currencyId")
|
||||
return@launch
|
||||
}
|
||||
// Convert using universal parser to account for regional separators
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ import kotlinx.coroutines.flow.StateFlow
|
|||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import com.tangem.utils.logging.TangemLogger
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
internal class FeeSelectorLogic @AssistedInject constructor(
|
||||
|
|
@ -277,7 +277,7 @@ internal class FeeSelectorLogic @AssistedInject constructor(
|
|||
val selectedToken = getSelectedTokenStatus(fee.feeTokenId).bind()
|
||||
val availableTokens = getAvailableFeeTokens().fold(
|
||||
ifLeft = { error ->
|
||||
Timber.e("Failed to get available fee tokens: $error")
|
||||
TangemLogger.e("Failed to get available fee tokens: $error")
|
||||
if (selectedToken.currency !is CryptoCurrency.Coin) {
|
||||
raise(error)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ import com.tangem.utils.extensions.stripZeroPlainString
|
|||
import com.tangem.utils.transformer.update
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import com.tangem.utils.logging.TangemLogger
|
||||
import java.math.BigDecimal
|
||||
import javax.inject.Inject
|
||||
import com.tangem.features.send.v2.api.entity.FeeSelectorUM as FeeSelectorUMRedesigned
|
||||
|
|
@ -374,7 +374,7 @@ internal class SendConfirmModel @Inject constructor(
|
|||
network = cryptoCurrency.network,
|
||||
).fold(
|
||||
ifLeft = { error ->
|
||||
Timber.e(error)
|
||||
TangemLogger.e("Error", error)
|
||||
_uiState.update(SendConfirmSendingStateTransformer(isSending = false))
|
||||
alertFactory.getGenericErrorState(
|
||||
onFailedTxEmailClick = {
|
||||
|
|
@ -470,7 +470,7 @@ internal class SendConfirmModel @Inject constructor(
|
|||
|
||||
val tokenToAdd = currenciesRepository.createTokenCurrency(cryptoCurrency, network)
|
||||
manageCryptoCurrenciesUseCase(accountId = accountId, add = tokenToAdd)
|
||||
.onLeft(Timber::e)
|
||||
.onLeft { TangemLogger.e("Error", it) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ import com.tangem.utils.coroutines.JobHolder
|
|||
import com.tangem.utils.coroutines.saveIn
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import com.tangem.utils.logging.TangemLogger
|
||||
import javax.inject.Inject
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
|
|
@ -271,7 +271,7 @@ internal class SendModel @Inject constructor(
|
|||
}
|
||||
|
||||
override fun onError(error: GetUserWalletError) {
|
||||
Timber.w(error.toString())
|
||||
TangemLogger.w(error.toString())
|
||||
showAlertError()
|
||||
}
|
||||
|
||||
|
|
@ -430,7 +430,7 @@ internal class SendModel @Inject constructor(
|
|||
.launchIn(modelScope)
|
||||
},
|
||||
ifLeft = { error ->
|
||||
Timber.w(error.toString())
|
||||
TangemLogger.w(error.toString())
|
||||
showAlertError()
|
||||
return@launch
|
||||
},
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ import com.tangem.utils.extensions.stripZeroPlainString
|
|||
import com.tangem.utils.transformer.update
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import com.tangem.utils.logging.TangemLogger
|
||||
import java.math.BigDecimal
|
||||
import javax.inject.Inject
|
||||
import com.tangem.features.send.v2.api.entity.FeeSelectorUM as FeeSelectorUMRedesigned
|
||||
|
|
@ -273,7 +273,7 @@ internal class NFTSendConfirmModel @Inject constructor(
|
|||
network = cryptoCurrency.network,
|
||||
).fold(
|
||||
ifLeft = { error ->
|
||||
Timber.e(error)
|
||||
TangemLogger.e("Error", error)
|
||||
_uiState.update(NFTSendConfirmSendingStateTransformer(isSending = false))
|
||||
alertFactory.getGenericErrorState(
|
||||
onFailedTxEmailClick = { onFailedTxEmailClick(error.localizedMessage.orEmpty()) },
|
||||
|
|
@ -297,7 +297,7 @@ internal class NFTSendConfirmModel @Inject constructor(
|
|||
|
||||
result.fold(
|
||||
ifLeft = { error ->
|
||||
Timber.e(error.toString())
|
||||
TangemLogger.e(error.toString())
|
||||
alertFactory.getSendTransactionErrorState(
|
||||
error = error,
|
||||
popBack = appRouter::pop,
|
||||
|
|
|
|||
|
|
@ -13,9 +13,13 @@ import com.tangem.core.decompose.navigation.Router
|
|||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.domain.account.status.supplier.MultiAccountStatusListSupplier
|
||||
import com.tangem.domain.account.usecase.IsAccountsModeEnabledUseCase
|
||||
import com.tangem.domain.models.account.filterCryptoPortfolio
|
||||
import com.tangem.domain.models.account.AccountStatus
|
||||
import com.tangem.domain.models.account.PaymentAccountStatusValue
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.network.CryptoCurrencyAddress
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.isLocked
|
||||
import com.tangem.domain.pay.TangemPayCryptoCurrencyFactory
|
||||
import com.tangem.domain.qrscanning.models.SourceType
|
||||
import com.tangem.domain.qrscanning.usecases.ListenToQrScanningUseCase
|
||||
import com.tangem.domain.qrscanning.usecases.ParseQrCodeUseCase
|
||||
|
|
@ -65,6 +69,7 @@ internal class SendDestinationModel @Inject constructor(
|
|||
private val listenToQrScanningUseCase: ListenToQrScanningUseCase,
|
||||
private val parseQrCodeUseCase: ParseQrCodeUseCase,
|
||||
private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase,
|
||||
private val tangemPayCryptoCurrencyFactory: TangemPayCryptoCurrencyFactory,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
private val multiAccountStatusListSupplier: MultiAccountStatusListSupplier,
|
||||
) : Model(), SendDestinationClickIntents {
|
||||
|
|
@ -217,8 +222,6 @@ internal class SendDestinationModel @Inject constructor(
|
|||
flow = getWalletsUseCase().conflate(),
|
||||
flow2 = multiAccountStatusListSupplier().conflate(),
|
||||
) { wallets, accountStatusLists ->
|
||||
val cryptoCurrencyNetwork = cryptoCurrency.network
|
||||
|
||||
coroutineScope {
|
||||
accountStatusLists.mapNotNull { accountStatusList ->
|
||||
val wallet = wallets
|
||||
|
|
@ -227,35 +230,55 @@ internal class SendDestinationModel @Inject constructor(
|
|||
?: return@mapNotNull null
|
||||
|
||||
async {
|
||||
accountStatusList.flattenCurrencies()
|
||||
.filter { it.currency.network.rawId == cryptoCurrencyNetwork.rawId }
|
||||
.mapNotNull { cryptoCurrencyStatus ->
|
||||
val address = cryptoCurrencyStatus.value.networkAddress?.defaultAddress?.value
|
||||
?: return@mapNotNull null
|
||||
|
||||
// Find the corresponding account from accountStatuses
|
||||
val account = accountStatusList.accountStatuses
|
||||
.filterCryptoPortfolio()
|
||||
.firstOrNull { accountStatus ->
|
||||
accountStatus.tokenList
|
||||
.flattenCurrencies()
|
||||
.any { it.currency.id == cryptoCurrencyStatus.currency.id }
|
||||
}?.account
|
||||
|
||||
DestinationWalletUM(
|
||||
name = wallet.name,
|
||||
address = address,
|
||||
cryptoCurrency = cryptoCurrencyStatus.currency,
|
||||
userWalletId = wallet.walletId,
|
||||
account = account,
|
||||
)
|
||||
accountStatusList.accountStatuses.flatMap { accountStatus ->
|
||||
when (accountStatus) {
|
||||
is AccountStatus.CryptoPortfolio -> accountStatus.getDestinationWalletUM(wallet)
|
||||
is AccountStatus.Payment -> listOfNotNull(accountStatus.getDestinationWalletUM(wallet))
|
||||
}
|
||||
}
|
||||
}
|
||||
}.awaitAll().flatten()
|
||||
}
|
||||
}.flowOn(dispatchers.default)
|
||||
}
|
||||
|
||||
private fun AccountStatus.CryptoPortfolio.getDestinationWalletUM(wallet: UserWallet): List<DestinationWalletUM> {
|
||||
return this.flattenCurrencies()
|
||||
.filter { it.currency.network.rawId == cryptoCurrency.network.rawId }
|
||||
.mapNotNull { cryptoCurrencyStatus ->
|
||||
val address = cryptoCurrencyStatus.value.networkAddress?.defaultAddress?.value
|
||||
?: return@mapNotNull null
|
||||
DestinationWalletUM(
|
||||
name = wallet.name,
|
||||
address = address,
|
||||
cryptoCurrency = cryptoCurrencyStatus.currency,
|
||||
userWalletId = wallet.walletId,
|
||||
account = account,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun AccountStatus.Payment.getDestinationWalletUM(wallet: UserWallet): DestinationWalletUM? {
|
||||
val contractAddress = (cryptoCurrency as? CryptoCurrency.Token)?.contractAddress ?: return null
|
||||
val address = when (val status = this.value) {
|
||||
is PaymentAccountStatusValue.Loaded -> status.cryptoBalance.depositAddress
|
||||
is PaymentAccountStatusValue.Locked -> status.cryptoBalance.depositAddress
|
||||
else -> return null
|
||||
}
|
||||
val currency = tangemPayCryptoCurrencyFactory.create(wallet).getOrNull() ?: return null
|
||||
return if (contractAddress.equals(currency.contractAddress, true)) {
|
||||
DestinationWalletUM(
|
||||
name = wallet.name,
|
||||
address = address,
|
||||
cryptoCurrency = currency,
|
||||
userWalletId = wallet.walletId,
|
||||
account = account,
|
||||
)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
private fun validate(address: String, memo: String?, type: EnterAddressSource? = null) {
|
||||
modelScope.launch {
|
||||
_uiState.update(SendDestinationValidationStartedTransformer)
|
||||
|
|
|
|||
|
|
@ -35,10 +35,11 @@ internal class SendRecipientWalletListConverter(
|
|||
return this.filterNotNull()
|
||||
.filter { destinationWallet ->
|
||||
val isCoin = destinationWallet.cryptoCurrency is CryptoCurrency.Coin
|
||||
val isPaymentAccount = destinationWallet.account is Account.Payment
|
||||
val isNotSameAddress = destinationWallet.address != senderAddress
|
||||
val isNotBlankAddress = destinationWallet.address.isNotBlank()
|
||||
|
||||
isNotBlankAddress && isCoin && (isNotSameAddress || isSelfSendAvailable)
|
||||
isNotBlankAddress && (isCoin || isPaymentAccount) && (isNotSameAddress || isSelfSendAvailable)
|
||||
}
|
||||
.groupBy { item -> item.name }
|
||||
.values.map { wallets ->
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue