diff --git a/app/src/main/assets/tangem-app-config b/app/src/main/assets/tangem-app-config index 4424b32de5..a837db2797 160000 --- a/app/src/main/assets/tangem-app-config +++ b/app/src/main/assets/tangem-app-config @@ -1 +1 @@ -Subproject commit 4424b32de5a80305cd3ca6eca219b09a16e940c5 +Subproject commit a837db27973dca80e51cf9590eb34e060bed1236 diff --git a/app/src/main/java/com/tangem/tap/common/feedback/AdditionalFeedbackInfo.kt b/app/src/main/java/com/tangem/tap/common/feedback/AdditionalFeedbackInfo.kt index e87ca04616..21fc321bbe 100644 --- a/app/src/main/java/com/tangem/tap/common/feedback/AdditionalFeedbackInfo.kt +++ b/app/src/main/java/com/tangem/tap/common/feedback/AdditionalFeedbackInfo.kt @@ -89,19 +89,19 @@ class AdditionalFeedbackInfo { fun updateOnSendError( walletManager: WalletManager, - amountToSend: Amount, + amountToSend: Amount?, feeAmount: Amount?, - destinationAddress: String, + destinationAddress: String?, ) { onSendErrorWalletInfo = createEmailWalletInfo(walletManager) - this.destinationAddress = destinationAddress - amount = amountToSend.value?.stripZeroPlainString() ?: "0" + this.destinationAddress = destinationAddress ?: "0" + amount = amountToSend?.value?.stripZeroPlainString() ?: "0" fee = if (feeAmount != null) { feeAmount.value?.stripZeroPlainString() ?: "0" } else { "Unable to receive" } - token = if (amountToSend.type is AmountType.Token) amountToSend.currencySymbol else "" + token = if (amountToSend?.type is AmountType.Token) amountToSend.currencySymbol else "" } private fun createEmailWalletInfo(walletManager: WalletManager): EmailWalletInfo { diff --git a/app/src/main/java/com/tangem/tap/common/redux/legacy/LegacyMiddleware.kt b/app/src/main/java/com/tangem/tap/common/redux/legacy/LegacyMiddleware.kt index 9ad974cdcd..7cf0e08bf1 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/legacy/LegacyMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/legacy/LegacyMiddleware.kt @@ -1,11 +1,16 @@ package com.tangem.tap.common.redux.legacy import com.tangem.domain.redux.LegacyAction +import com.tangem.domain.tokens.utils.convertToAmount +import com.tangem.tap.common.extensions.inject import com.tangem.tap.common.feedback.RateCanBeBetterEmail import com.tangem.tap.common.feedback.SendTransactionFailedEmail import com.tangem.tap.common.redux.AppState import com.tangem.tap.common.redux.global.GlobalAction +import com.tangem.tap.proxy.redux.DaggerGraphState +import com.tangem.tap.scope import com.tangem.tap.store +import kotlinx.coroutines.launch import org.rekotlin.Middleware internal object LegacyMiddleware { @@ -22,9 +27,29 @@ internal object LegacyMiddleware { ) } is LegacyAction.SendEmailTransactionFailed -> { - store.state.globalState.feedbackManager?.sendEmail( - SendTransactionFailedEmail(action.errorMessage), - ) + if (store.inject(DaggerGraphState::feedbackManagerFeatureToggles).isLocalLogsEnabled) { + store.state.globalState.feedbackManager?.sendEmail( + SendTransactionFailedEmail(action.errorMessage), + ) + } else { + scope.launch { + store.inject(DaggerGraphState::walletManagersFacade) + .getOrCreateWalletManager( + userWalletId = action.userWalletId, + network = action.cryptoCurrency.network, + )?.let { walletManager -> + store.state.globalState.feedbackManager?.infoHolder?.updateOnSendError( + walletManager = walletManager, + amountToSend = action.amount?.convertToAmount(action.cryptoCurrency), + feeAmount = action.fee?.convertToAmount(action.cryptoCurrency), + destinationAddress = action.destinationAddress, + ) + } + store.state.globalState.feedbackManager?.sendEmail( + SendTransactionFailedEmail(action.errorMessage), + ) + } + } } } next(action) diff --git a/core/analytics/src/main/java/com/tangem/core/analytics/Analytics.kt b/core/analytics/src/main/java/com/tangem/core/analytics/Analytics.kt index 790de00ea3..239573bed5 100644 --- a/core/analytics/src/main/java/com/tangem/core/analytics/Analytics.kt +++ b/core/analytics/src/main/java/com/tangem/core/analytics/Analytics.kt @@ -6,6 +6,7 @@ import com.tangem.utils.coroutines.FeatureCoroutineExceptionHandler import kotlinx.coroutines.* import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock +import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.Executors /** @@ -22,7 +23,7 @@ object Analytics : GlobalAnalyticsEventHandler { private val analyticsScope: CoroutineScope by lazy { createScope() } private val handlers = mutableMapOf() - private val paramsInterceptors = mutableMapOf() + private val paramsInterceptors = ConcurrentHashMap() private val analyticsFilters = mutableSetOf() private val analyticsMutex = Mutex() diff --git a/core/featuretoggles/src/main/assets/configs/feature_toggles_config.json b/core/featuretoggles/src/main/assets/configs/feature_toggles_config.json index bf362e041c..a4472cf056 100644 --- a/core/featuretoggles/src/main/assets/configs/feature_toggles_config.json +++ b/core/featuretoggles/src/main/assets/configs/feature_toggles_config.json @@ -21,11 +21,11 @@ }, { "name": "WC_SOLANA_TX_SIGN_ENABLED", - "version": "5.11.0" + "version": "undefined" }, { "name": "TOKEN_LIST_LCE_ENABLED", - "version": "5.11.0" + "version": "5.12.0" }, { "name": "CARDANO_TOKENS_SUPPORT_ENABLED", diff --git a/core/res/src/main/res/values-ru/strings.xml b/core/res/src/main/res/values-ru/strings.xml index 1135d892dc..0c2f9e38e2 100644 --- a/core/res/src/main/res/values-ru/strings.xml +++ b/core/res/src/main/res/values-ru/strings.xml @@ -668,7 +668,7 @@ Используйте %s или отсканируйте карту, чтобы разблокировать доступ к вашему кошельку Пожалуйста, выведите все средства из этого кошелька, сбросьте его к заводским настройкам и создайте новый. Доступ к текущему кошельку будет утерян. Ошибка активации - По решению разработчиков сети BNB, стандарт BEP-2 перестанет поддерживаться в июне 2024 года. Чтобы не потерять свои активы, их необходимо преобразовать в стандарт BEP-20. Используйте функцию обмена в приложении чтобы перевести их в cеть BNB Smart Chain. + По решению разработчиков сети BNB стандарт BEP-2 перестанет поддерживаться в июне 2024 года. Чтобы не потерять активы, их необходимо преобразовать в стандарт BEP-20. Используйте функцию обмена в приложении или сторонние сервисы, чтобы перевести средства в cеть BNB Smart Chain. Отключение сети BNB Beacon Chain Можно лучше Нравится diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml index 8bbaa40db7..0e761dde1b 100644 --- a/core/res/src/main/res/values/strings.xml +++ b/core/res/src/main/res/values/strings.xml @@ -661,7 +661,7 @@ Use %s or scan a card to unlock access to your wallet Please withdraw all funds from this wallet, reset it to factory settings, and create a new one. Access to the current wallet will be lost. Activation error - According to BNB network developers, support for the BEP-2 standard will end in June 2024. To avoid losing assets with this standard, please convert them to the BEP-20 standard. Use our swap service to transfer them to the BNB Smart Chain network. + According to BNB network developers, support for the BEP-2 standard will end in June 2024. To avoid losing assets with this standard, please convert them to the BEP-20 standard. Use our swap service or third-party services to transfer funds to the BNB Smart Chain network. BNB Beacon Chain will shut down Could be better Like it diff --git a/domain/legacy/src/main/java/com/tangem/domain/redux/LegacyAction.kt b/domain/legacy/src/main/java/com/tangem/domain/redux/LegacyAction.kt index 826ba5a966..3e0b022afd 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/redux/LegacyAction.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/redux/LegacyAction.kt @@ -1,7 +1,10 @@ package com.tangem.domain.redux import com.tangem.domain.models.scan.ScanResponse +import com.tangem.domain.tokens.model.CryptoCurrency +import com.tangem.domain.wallets.models.UserWalletId import org.rekotlin.Action +import java.math.BigDecimal sealed interface LegacyAction : Action { @@ -16,6 +19,20 @@ sealed interface LegacyAction : Action { /** * Sending an email to support when sending transaction failed + * + * @param cryptoCurrency current currency + * @param userWalletId selected user wallet id + * @param amount sending amount + * @param fee spending fee + * @param destinationAddress recipient address + * @param errorMessage sending error */ - data class SendEmailTransactionFailed(val errorMessage: String) : LegacyAction + data class SendEmailTransactionFailed( + val cryptoCurrency: CryptoCurrency, + val userWalletId: UserWalletId, + val amount: BigDecimal?, + val fee: BigDecimal?, + val destinationAddress: String?, + val errorMessage: String, + ) : LegacyAction } \ No newline at end of file diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/recipient/SendRecipientHistoryListConverter.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/recipient/SendRecipientHistoryListConverter.kt index 3b555a7e21..8a8576775e 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/recipient/SendRecipientHistoryListConverter.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/recipient/SendRecipientHistoryListConverter.kt @@ -1,5 +1,6 @@ package com.tangem.features.send.impl.presentation.state.recipient +import com.tangem.common.extensions.isZero import com.tangem.core.ui.extensions.TextReference import com.tangem.core.ui.extensions.stringReference import com.tangem.core.ui.extensions.wrappedList @@ -39,7 +40,8 @@ internal class SendRecipientHistoryListConverter( } else { item.sourceType is TxHistoryItem.SourceType.Single } - isTransfer && isSingleAddress && isNotContract + val notZero = !item.amount.isZero() + isTransfer && isSingleAddress && isNotContract && item.isOutgoing && notZero } .take(RECENT_LIST_SIZE) .mapIndexed { index, tx -> diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt index d003acc8d5..978083d67d 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt @@ -442,6 +442,7 @@ internal class SendViewModel @Inject constructor( getFixedTxHistoryItemsUseCase.getSync( userWalletId = userWalletId, currency = cryptoCurrency, + pageSize = RECENT_TX_SIZE, ).getOrElse { emptyList() } } uiState = recipientStateFactory.onLoadedHistoryList(txHistory = txHistoryList) @@ -530,7 +531,31 @@ internal class SendViewModel @Inject constructor( } override fun onFailedTxEmailClick(errorMessage: String) { - reduxStateHolder.dispatch(LegacyAction.SendEmailTransactionFailed(errorMessage)) + val recipient = uiState.recipientState?.addressTextField?.value + val feeValue = uiState.feeState?.fee?.amount?.value + val amountValue = uiState.amountState?.amountTextField?.cryptoAmount?.value + + val receivingAmount = if (amountValue != null && feeValue != null) { + checkAndCalculateSubtractedAmount( + isAmountSubtractAvailable = isAmountSubtractAvailable, + cryptoCurrencyStatus = cryptoCurrencyStatus, + amountValue = amountValue, + feeValue = feeValue, + reduceAmountBy = uiState.sendState?.reduceAmountBy ?: BigDecimal.ZERO, + ) + } else { + null + } + reduxStateHolder.dispatch( + LegacyAction.SendEmailTransactionFailed( + cryptoCurrency = cryptoCurrency, + userWalletId = userWalletId, + amount = receivingAmount, + fee = feeValue, + destinationAddress = recipient, + errorMessage = errorMessage, + ), + ) } override fun onTokenDetailsClick(userWalletId: UserWalletId, currency: CryptoCurrency) = @@ -981,6 +1006,7 @@ internal class SendViewModel @Inject constructor( const val CHECK_FEE_UPDATE_DELAY = 60_000L const val BALANCE_UPDATE_DELAY = 11_000L const val RECENT_LOAD_DELAY = 500L + const val RECENT_TX_SIZE = 100 const val RU_LOCALE = "ru" const val EN_LOCALE = "en" diff --git a/features/swap/domain/models/src/main/java/com/tangem/feature/swap/domain/models/SwapAmount.kt b/features/swap/domain/models/src/main/java/com/tangem/feature/swap/domain/models/SwapAmount.kt index c37e6fbc96..4b451b4dc3 100644 --- a/features/swap/domain/models/src/main/java/com/tangem/feature/swap/domain/models/SwapAmount.kt +++ b/features/swap/domain/models/src/main/java/com/tangem/feature/swap/domain/models/SwapAmount.kt @@ -2,6 +2,7 @@ package com.tangem.feature.swap.domain.models import com.tangem.utils.toFormattedString import java.math.BigDecimal +import java.math.RoundingMode data class SwapAmount( val value: BigDecimal, @@ -39,10 +40,5 @@ fun createFromAmountWithOffset(amountWithOffset: String, decimals: Int): SwapAmo @Throws(IllegalStateException::class) fun SwapAmount.toStringWithRightOffset(): String { - return value.movePointRight(decimals).toPlainString() -} - -@Throws(IllegalStateException::class) -fun SwapAmount.toStringWithLeftOffset(): String { - return value.movePointLeft(decimals).toPlainString() + return value.setScale(decimals, RoundingMode.HALF_DOWN).movePointRight(decimals).toPlainString() } \ No newline at end of file diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/models/states/FeeItemState.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/models/states/FeeItemState.kt index e01a8b8058..8c3218aa96 100644 --- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/models/states/FeeItemState.kt +++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/models/states/FeeItemState.kt @@ -5,6 +5,10 @@ import com.tangem.feature.swap.domain.models.ui.FeeType sealed class FeeItemState { + /** + * @param amountCrypto - crypto amount formatted with symbol + * @param amountFiatFormatted - formatted fiat amount + */ data class Content( val feeType: FeeType, val title: TextReference, diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/StateBuilder.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/StateBuilder.kt index 1d6b6a1bb3..a49c381eff 100644 --- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/StateBuilder.kt +++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/StateBuilder.kt @@ -471,9 +471,7 @@ internal class StateBuilder( warnings.add( SwapWarning.GeneralWarning( createNetworkFeeCoverageNotificationConfig( - quoteModel.fromTokenInfo.tokenAmount.getFormattedCryptoAmount( - quoteModel.fromTokenInfo.cryptoCurrencyStatus.currency, - ), + fee.feeCryptoFormatted, fee.feeFiatFormatted, ), ), @@ -578,7 +576,7 @@ internal class StateBuilder( warnings.add(getWarningForError(dataError, fromToken.cryptoCurrencyStatus.currency)) if (includeFeeInAmount is IncludeFeeInAmount.Included && uiStateHolder.fee is FeeItemState.Content) { val feeCoverageNotification = createNetworkFeeCoverageNotificationConfig( - fromToken.tokenAmount.getFormattedCryptoAmount(fromToken.cryptoCurrencyStatus.currency), + uiStateHolder.fee.amountCrypto, uiStateHolder.fee.amountFiatFormatted, ) warnings.add(SwapWarning.GeneralWarning(feeCoverageNotification)) diff --git a/gradle/dependencies.toml b/gradle/dependencies.toml index 4c77d4b171..2ce99c03eb 100644 --- a/gradle/dependencies.toml +++ b/gradle/dependencies.toml @@ -87,7 +87,7 @@ markdown = "0.7.2" # endregion Other libraries # region Tangem -tangemBlockchainSdk = "release-app_5.12-664" +tangemBlockchainSdk = "release-app_5.12-667" #tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds tangemCardSdk = "release-app_5.12-364" #tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^