diff --git a/core/res/src/main/res/values-ru/strings.xml b/core/res/src/main/res/values-ru/strings.xml index fba85fe955..aa18939439 100644 --- a/core/res/src/main/res/values-ru/strings.xml +++ b/core/res/src/main/res/values-ru/strings.xml @@ -564,6 +564,7 @@ ≈ %1$s (вкл. комиссию: %2$s) %s будет отправлено Транзакция успешно подписана и отправлена в блокчейн. Баланс будет обновлен через некоторое время + %1$s — это монета в сети Tron. Чтобы рассчитать комиссию и совершить транзакцию, вам необходимо внести немного Tron (TRX) на свой адрес. Неверный адрес Транзакция отправлена Подготовьтесь к сканированию карты, которую вы хотите настроить. diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml index 2c36f14fdf..954e7e59ca 100644 --- a/core/res/src/main/res/values/strings.xml +++ b/core/res/src/main/res/values/strings.xml @@ -627,6 +627,7 @@ ≈ %1$s (inc. fee: %2$s) %s will be sent Transaction has been successfully signed and sent to the blockchain node. Wallet balance will be updated in a while + %1$s is an asset in the Tron network. To calculate the fee and make a transaction you need to deposit some Tron(TRX) in your account. Invalid address %1$s (%2$s) Transaction sent diff --git a/domain/transaction/src/main/java/com/tangem/domain/transaction/error/FeeErrorsMapper.kt b/domain/transaction/src/main/java/com/tangem/domain/transaction/error/FeeErrorsMapper.kt new file mode 100644 index 0000000000..718ccb6f9b --- /dev/null +++ b/domain/transaction/src/main/java/com/tangem/domain/transaction/error/FeeErrorsMapper.kt @@ -0,0 +1,13 @@ +package com.tangem.domain.transaction.error + +import com.tangem.blockchain.common.BlockchainSdkError +import com.tangem.blockchain.extensions.Result + +fun Result.Failure.mapToFeeError(): GetFeeError { + return when (this.error) { + is BlockchainSdkError.Tron.AccountActivationError -> { + GetFeeError.BlockchainErrors.TronActivationError + } + else -> GetFeeError.DataError(this.error) + } +} \ No newline at end of file diff --git a/domain/transaction/src/main/java/com/tangem/domain/transaction/error/GetFeeError.kt b/domain/transaction/src/main/java/com/tangem/domain/transaction/error/GetFeeError.kt index f2e3f7f60f..bc57770c0f 100644 --- a/domain/transaction/src/main/java/com/tangem/domain/transaction/error/GetFeeError.kt +++ b/domain/transaction/src/main/java/com/tangem/domain/transaction/error/GetFeeError.kt @@ -2,5 +2,9 @@ package com.tangem.domain.transaction.error sealed class GetFeeError { data class DataError(val cause: Throwable?) : GetFeeError() - object UnknownError : GetFeeError() + data object UnknownError : GetFeeError() + + sealed class BlockchainErrors : GetFeeError() { + data object TronActivationError : BlockchainErrors() + } } \ No newline at end of file diff --git a/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/EstimateFeeUseCase.kt b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/EstimateFeeUseCase.kt index 2a32a62d43..134cb9f3f5 100644 --- a/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/EstimateFeeUseCase.kt +++ b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/EstimateFeeUseCase.kt @@ -12,6 +12,7 @@ import com.tangem.domain.demo.DemoConfig import com.tangem.domain.demo.DemoTransactionSender import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.domain.transaction.error.GetFeeError +import com.tangem.domain.transaction.error.mapToFeeError import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.domain.wallets.models.UserWallet import kotlinx.coroutines.flow.Flow @@ -47,7 +48,7 @@ class EstimateFeeUseCase( val maybeFee = when (result) { is Result.Success -> result.data.right() - is Result.Failure -> GetFeeError.DataError(result.error).left() + is Result.Failure -> result.mapToFeeError().left() null -> GetFeeError.UnknownError.left() } emit(maybeFee) diff --git a/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/GetFeeUseCase.kt b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/GetFeeUseCase.kt index 2f113a02a0..548a43ab6c 100644 --- a/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/GetFeeUseCase.kt +++ b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/GetFeeUseCase.kt @@ -10,6 +10,7 @@ import com.tangem.domain.demo.DemoConfig import com.tangem.domain.demo.DemoTransactionSender import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.domain.transaction.error.GetFeeError +import com.tangem.domain.transaction.error.mapToFeeError import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.domain.wallets.models.UserWallet import java.math.BigDecimal @@ -47,7 +48,7 @@ class GetFeeUseCase( val maybeFee = when (result) { is Result.Success -> result.data - is Result.Failure -> raise(GetFeeError.DataError(result.error)) + is Result.Failure -> raise(result.mapToFeeError()) } maybeFee }, diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/errors/FeeErrorStateMapper.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/errors/FeeErrorStateMapper.kt new file mode 100644 index 0000000000..ab218f7fe0 --- /dev/null +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/errors/FeeErrorStateMapper.kt @@ -0,0 +1,19 @@ +package com.tangem.features.send.impl.presentation.errors + +import com.tangem.domain.transaction.error.GetFeeError +import com.tangem.features.send.impl.presentation.state.fee.FeeSelectorState + +internal class FeeErrorStateMapper { + + fun getFeeError(loadFeeError: GetFeeError?, tokenName: String): FeeSelectorState.Error { + return when (loadFeeError) { + GetFeeError.BlockchainErrors.TronActivationError -> FeeSelectorState.Error.TronAccountActivationError( + tokenName, + ) + is GetFeeError.DataError, + GetFeeError.UnknownError, + null, + -> FeeSelectorState.Error.NetworkError + } + } +} \ No newline at end of file diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendNotification.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendNotification.kt index 65318c9c39..017c91f8d4 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendNotification.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendNotification.kt @@ -157,6 +157,14 @@ internal sealed class SendNotification(val config: NotificationConfig) { ), ) + data class TronAccountNotActivated(val tokenName: String) : Warning( + title = resourceReference(R.string.send_fee_unreachable_error_title), + subtitle = resourceReference( + R.string.send_tron_account_activation_error, + wrappedList(tokenName), + ), + ) + data class FeeCoverageNotification(val cryptoAmount: String, val fiatAmount: String) : Warning( title = resourceReference(R.string.send_network_fee_warning_title), subtitle = resourceReference( diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/confirm/SendNotificationFactory.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/confirm/SendNotificationFactory.kt index 98001756d9..a4e3bcbf9c 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/confirm/SendNotificationFactory.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/confirm/SendNotificationFactory.kt @@ -126,8 +126,18 @@ internal class SendNotificationFactory( } private fun MutableList.addFeeUnreachableNotification(feeSelectorState: FeeSelectorState) { - if (feeSelectorState is FeeSelectorState.Error) { - add(SendNotification.Warning.NetworkFeeUnreachable(clickIntents::feeReload)) + when (feeSelectorState) { + is FeeSelectorState.Error.TronAccountActivationError -> add( + SendNotification.Warning.TronAccountNotActivated( + feeSelectorState.tokenName, + ), + ) + is FeeSelectorState.Error.NetworkError -> add( + SendNotification.Warning.NetworkFeeUnreachable(clickIntents::feeReload), + ) + else -> { + /* do nothing */ + } } } diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/FeeNotificationFactory.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/FeeNotificationFactory.kt index 229568a930..aba37ba2ea 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/FeeNotificationFactory.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/FeeNotificationFactory.kt @@ -1,6 +1,9 @@ package com.tangem.features.send.impl.presentation.state.fee -import com.tangem.features.send.impl.presentation.state.* +import com.tangem.features.send.impl.presentation.state.SendNotification +import com.tangem.features.send.impl.presentation.state.SendUiState +import com.tangem.features.send.impl.presentation.state.SendUiStateType +import com.tangem.features.send.impl.presentation.state.StateRouter import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents import com.tangem.utils.Provider import kotlinx.collections.immutable.persistentListOf @@ -21,13 +24,25 @@ internal class FeeNotificationFactory( val state = currentStateProvider() val feeState = state.getFeeState(stateRouterProvider().isEditState) ?: return@map persistentListOf() buildList { - addFeeUnreachableNotification(feeState.feeSelectorState) + addFeeUnreachableNotification( + feeState.feeSelectorState, + ) }.toImmutableList() } private fun MutableList.addFeeUnreachableNotification(feeSelectorState: FeeSelectorState) { - if (feeSelectorState is FeeSelectorState.Error) { - add(SendNotification.Warning.NetworkFeeUnreachable(clickIntents::feeReload)) + when (feeSelectorState) { + is FeeSelectorState.Error.TronAccountActivationError -> add( + SendNotification.Warning.TronAccountNotActivated( + feeSelectorState.tokenName, + ), + ) + is FeeSelectorState.Error.NetworkError -> add( + SendNotification.Warning.NetworkFeeUnreachable(clickIntents::feeReload), + ) + else -> { + /* do nothing */ + } } } } \ No newline at end of file diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/FeeSelectorState.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/FeeSelectorState.kt index cd1fe29939..6ee78a7939 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/FeeSelectorState.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/FeeSelectorState.kt @@ -17,7 +17,10 @@ internal sealed class FeeSelectorState { data object Loading : FeeSelectorState() - data object Error : FeeSelectorState() + sealed class Error : FeeSelectorState() { + data object NetworkError : Error() + data class TronAccountActivationError(val tokenName: String) : Error() + } } enum class FeeType { diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/FeeStateFactory.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/FeeStateFactory.kt index e933b89477..3a30e424b9 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/FeeStateFactory.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/FeeStateFactory.kt @@ -99,13 +99,13 @@ internal class FeeStateFactory( ) } - fun onFeeOnErrorState(): SendUiState { + fun onFeeOnErrorState(feeError: FeeSelectorState.Error): SendUiState { val state = currentStateProvider() val isEditState = stateRouterProvider().isEditState return state.copyWrapped( isEditState = isEditState, feeState = state.getFeeState(isEditState)?.copy( - feeSelectorState = FeeSelectorState.Error, + feeSelectorState = feeError, ), sendState = state.sendState?.copy( isPrimaryButtonEnabled = false, diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/previewdata/FeeStatePreviewData.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/previewdata/FeeStatePreviewData.kt index c024b39ee0..7d00f7102d 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/previewdata/FeeStatePreviewData.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/previewdata/FeeStatePreviewData.kt @@ -102,6 +102,6 @@ internal object FeeStatePreviewData { ) val errorFeeState = feeState.copy( - feeSelectorState = FeeSelectorState.Error, + feeSelectorState = FeeSelectorState.Error.NetworkError, ) } \ No newline at end of file diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/fee/SendSpeedSelectorItem.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/fee/SendSpeedSelectorItem.kt index 08e3ff9853..f7aacce75a 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/fee/SendSpeedSelectorItem.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/fee/SendSpeedSelectorItem.kt @@ -98,7 +98,7 @@ private fun FeeError(feeSelectorState: FeeSelectorState) { Row { SpacerWMax() AnimatedVisibility( - visible = feeSelectorState == FeeSelectorState.Error, + visible = feeSelectorState is FeeSelectorState.Error, label = "Fee Error State Change", modifier = Modifier.align(Alignment.CenterVertically), ) { diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/send/FeeBlock.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/send/FeeBlock.kt index 11c4f4ebab..0339ddc783 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/send/FeeBlock.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/send/FeeBlock.kt @@ -105,7 +105,7 @@ private fun BoxScope.FeeError(feeSelectorState: FeeSelectorState) { label = "Fee Error State Change", modifier = Modifier.align(Alignment.CenterEnd), ) { - if (it == FeeSelectorState.Error) { + if (it is FeeSelectorState.Error) { Text( text = BigDecimalFormatter.EMPTY_BALANCE_SIGN, color = TangemTheme.colors.text.primary1, 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 446343bfeb..a57a241ebf 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 @@ -45,6 +45,7 @@ import com.tangem.features.send.impl.presentation.analytics.SendAnalyticEvents import com.tangem.features.send.impl.presentation.analytics.SendScreenSource import com.tangem.features.send.impl.presentation.analytics.utils.SendScreenAnalyticSender import com.tangem.features.send.impl.presentation.domain.AvailableWallet +import com.tangem.features.send.impl.presentation.errors.FeeErrorStateMapper import com.tangem.features.send.impl.presentation.state.* import com.tangem.features.send.impl.presentation.state.amount.AmountStateFactory import com.tangem.features.send.impl.presentation.state.confirm.SendNotificationFactory @@ -120,6 +121,8 @@ internal class SendViewModel @Inject constructor( var stateRouter: StateRouter by Delegates.notNull() private set + private val feeErrorHandler = FeeErrorStateMapper() + private val stateFactory = SendStateFactory( clickIntents = this, stateRouterProvider = Provider { stateRouter }, @@ -711,20 +714,24 @@ internal class SendViewModel @Inject constructor( uiState.value = feeStateFactory.onFeeOnLoadedState(it) sendIdleTimer = SystemClock.elapsedRealtime() }, - ifLeft = { - onFeeLoadFailed(isShowStatus) + ifLeft = { loadFeeError -> + onFeeLoadFailed(isShowStatus, loadFeeError) }, ) if (result == null) { - onFeeLoadFailed(isShowStatus) + onFeeLoadFailed(isShowStatus, null) } updateNotifications() updateFeeNotifications() }.saveIn(feeJobHolder) } - private fun onFeeLoadFailed(isShowStatus: Boolean) { - if (isShowStatus) uiState.value = feeStateFactory.onFeeOnErrorState() + private fun onFeeLoadFailed(isShowStatus: Boolean, loadFeeError: GetFeeError?) { + if (isShowStatus) { + uiState.value = feeStateFactory.onFeeOnErrorState( + feeErrorHandler.getFeeError(loadFeeError, cryptoCurrency.name), + ) + } } private suspend fun checkIfSubtractAvailable() { diff --git a/gradle/dependencies.toml b/gradle/dependencies.toml index cc82331baf..ce194116f9 100644 --- a/gradle/dependencies.toml +++ b/gradle/dependencies.toml @@ -88,7 +88,7 @@ markdown = "0.7.2" # endregion Other libraries # region Tangem -tangemBlockchainSdk = "develop-700" +tangemBlockchainSdk = "develop-702" #tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds tangemCardSdk = "develop-375" #tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^