diff --git a/core/datasource/src/main/java/com/tangem/datasource/utils/NetworkLogsSaveInterceptor.kt b/core/datasource/src/main/java/com/tangem/datasource/utils/NetworkLogsSaveInterceptor.kt
index 58b21f35dd..9e3d88dcb4 100644
--- a/core/datasource/src/main/java/com/tangem/datasource/utils/NetworkLogsSaveInterceptor.kt
+++ b/core/datasource/src/main/java/com/tangem/datasource/utils/NetworkLogsSaveInterceptor.kt
@@ -44,7 +44,12 @@ class NetworkLogsSaveInterceptor(
throw e
}
- if (restrictedForLogURLs.contains(request.url.host + request.url.encodedPath)) {
+ val host = request.url.host
+ val path = request.url.encodedPath
+ val isRestrictedUrl = restrictedForLogURLs.contains(host + path)
+ val isRestrictedHost = restrictedForLogHosts.any { host.contains(it) }
+
+ if (isRestrictedUrl || isRestrictedHost) {
logResponseWithEmptyMessage(response, startNs)
} else {
logResponseMessage(response, startNs)
@@ -222,5 +227,8 @@ class NetworkLogsSaveInterceptor(
val restrictedForLogURLs = listOf(
"api.stakek.it/v1/yields/enabled",
)
+ val restrictedForLogHosts = listOf(
+ "us.paera.com",
+ )
}
}
\ No newline at end of file
diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml
index 7f0604d2d7..97beabdc7a 100644
--- a/core/res/src/main/res/values/strings.xml
+++ b/core/res/src/main/res/values/strings.xml
@@ -1453,6 +1453,7 @@
Failed to issue card
A technical error has occurred, please try again by clicking the button below.
A technical error has occurred, please contact support.
+ Go to Support
It usually takes up to 15 minutes
Setting up your Tangem Card
Issuing your card
diff --git a/data/visa/src/main/kotlin/com/tangem/data/pay/DefaultTangemPayCryptoCurrencyFactory.kt b/data/visa/src/main/kotlin/com/tangem/data/pay/DefaultTangemPayCryptoCurrencyFactory.kt
index a768bf84b1..505383a099 100644
--- a/data/visa/src/main/kotlin/com/tangem/data/pay/DefaultTangemPayCryptoCurrencyFactory.kt
+++ b/data/visa/src/main/kotlin/com/tangem/data/pay/DefaultTangemPayCryptoCurrencyFactory.kt
@@ -2,14 +2,12 @@ package com.tangem.data.pay
import arrow.core.Either
import arrow.core.Either.Companion.catch
-import com.squareup.moshi.Moshi
import com.tangem.blockchain.blockchains.ethereum.Chain
import com.tangem.blockchainsdk.utils.ExcludedBlockchains
import com.tangem.core.error.UniversalError
import com.tangem.data.common.currency.CryptoCurrencyFactory
import com.tangem.data.common.network.NetworkFactory
import com.tangem.data.pay.util.TangemPayErrorConverter
-import com.tangem.datasource.di.NetworkMoshi
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.pay.TangemPayCryptoCurrencyFactory
@@ -26,8 +24,8 @@ private const val TOKEN_CONTRACT_ADDRESS = "0x3c499c542cef5e3811e1192ce70d8cc03d
private const val TOKEN_DECIMALS = 6
internal class DefaultTangemPayCryptoCurrencyFactory @Inject constructor(
- @NetworkMoshi moshi: Moshi,
excludedBlockchains: ExcludedBlockchains,
+ private val errorConverter: TangemPayErrorConverter,
) : TangemPayCryptoCurrencyFactory {
private val cryptoCurrencyFactory by lazy(mode = LazyThreadSafetyMode.NONE) {
@@ -37,8 +35,6 @@ internal class DefaultTangemPayCryptoCurrencyFactory @Inject constructor(
NetworkFactory(excludedBlockchains)
}
- private val errorConverter by lazy(mode = LazyThreadSafetyMode.NONE) { TangemPayErrorConverter(moshi) }
-
override fun create(userWallet: UserWallet, chainId: Int): Either {
return catch {
val chain = requireNotNull(Chain.entries.find { it.id == chainId }) { "Can not find chain with $chainId" }
diff --git a/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultTangemPayCardDetailsRepository.kt b/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultTangemPayCardDetailsRepository.kt
index 8af56ff827..1dafcfd572 100644
--- a/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultTangemPayCardDetailsRepository.kt
+++ b/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultTangemPayCardDetailsRepository.kt
@@ -1,8 +1,12 @@
package com.tangem.data.pay.repository
import arrow.core.Either
+import arrow.core.left
+import arrow.core.raise.catch
+import arrow.core.right
import com.tangem.core.error.UniversalError
import com.tangem.data.pay.util.RainCryptoUtil
+import com.tangem.data.pay.util.TangemPayErrorConverter
import com.tangem.data.visa.config.VisaLibLoader
import com.tangem.datasource.api.common.config.ApiConfig
import com.tangem.datasource.api.common.config.ApiEnvironment
@@ -40,6 +44,7 @@ internal class DefaultTangemPayCardDetailsRepository @Inject constructor(
private val rainCryptoUtil: RainCryptoUtil,
private val storage: TangemPayStorage,
private val cardFrozenStateStore: TangemPayCardFrozenStateStore,
+ private val errorConverter: TangemPayErrorConverter,
) : TangemPayCardDetailsRepository {
private val pollingScope = CoroutineScope(Dispatchers.IO + SupervisorJob())
@@ -64,37 +69,39 @@ internal class DefaultTangemPayCardDetailsRepository @Inject constructor(
}
override suspend fun revealCardDetails(userWalletId: UserWalletId): Either {
- return requestHelper.runWithErrorLogs(TAG) {
- val publicKeyBase64 = getPublicKeyBase64()
- val (secretKeyBytes, sessionId) = rainCryptoUtil.generateSecretKeyAndSessionId(publicKeyBase64)
+ return catch(
+ block = {
+ val publicKeyBase64 = getPublicKeyBase64()
+ val (secretKeyBytes, sessionId) = rainCryptoUtil.generateSecretKeyAndSessionId(publicKeyBase64)
+ val result = requestHelper.performRequest(userWalletId = userWalletId) { authHeader ->
+ tangemPayApi.revealCardDetails(
+ authHeader = authHeader,
+ body = CardDetailsRequest(sessionId = sessionId),
+ )
+ }.getOrNull()?.result ?: error("Cannot reveal card details")
- val result = requestHelper.request(userWalletId) { authHeader ->
- tangemPayApi.revealCardDetails(
- authHeader = authHeader,
- body = CardDetailsRequest(sessionId = sessionId),
+ val pan = rainCryptoUtil.decryptSecret(
+ base64Secret = result.pan.secret,
+ base64Iv = result.pan.iv,
+ secretKeyBytes = secretKeyBytes,
)
- }.result ?: error("Cannot reveal card details")
- val pan = rainCryptoUtil.decryptSecret(
- base64Secret = result.pan.secret,
- base64Iv = result.pan.iv,
- secretKeyBytes = secretKeyBytes,
- )
+ val cvv = rainCryptoUtil.decryptSecret(
+ base64Secret = result.cvv.secret,
+ base64Iv = result.cvv.iv,
+ secretKeyBytes = secretKeyBytes,
+ )
+ secretKeyBytes.fill(0)
- val cvv = rainCryptoUtil.decryptSecret(
- base64Secret = result.cvv.secret,
- base64Iv = result.cvv.iv,
- secretKeyBytes = secretKeyBytes,
- )
- secretKeyBytes.fill(0)
-
- TangemPayCardDetails(
- pan = pan,
- cvv = cvv,
- expirationYear = result.expirationYear,
- expirationMonth = result.expirationMonth,
- )
- }
+ TangemPayCardDetails(
+ pan = pan,
+ cvv = cvv,
+ expirationYear = result.expirationYear,
+ expirationMonth = result.expirationMonth,
+ ).right()
+ },
+ catch = { errorConverter.convert(it).left() },
+ )
}
override suspend fun setPin(userWalletId: UserWalletId, pin: String): Either {
diff --git a/data/visa/src/main/kotlin/com/tangem/data/pay/repository/TangemPayRequestPerformer.kt b/data/visa/src/main/kotlin/com/tangem/data/pay/repository/TangemPayRequestPerformer.kt
index 7e6b5ec06c..788aafe9d8 100644
--- a/data/visa/src/main/kotlin/com/tangem/data/pay/repository/TangemPayRequestPerformer.kt
+++ b/data/visa/src/main/kotlin/com/tangem/data/pay/repository/TangemPayRequestPerformer.kt
@@ -5,14 +5,12 @@ import arrow.core.getOrElse
import arrow.core.left
import arrow.core.raise.catch
import arrow.core.right
-import com.squareup.moshi.Moshi
import com.squareup.wire.Instant
import com.tangem.data.pay.util.TangemPayErrorConverter
import com.tangem.datasource.api.common.response.ApiResponse
import com.tangem.datasource.api.pay.TangemPayAuthApi
import com.tangem.datasource.api.pay.models.request.RefreshCustomerWalletAccessTokenRequest
import com.tangem.datasource.api.pay.models.response.TangemPayGetTokensResponse
-import com.tangem.datasource.di.NetworkMoshi
import com.tangem.datasource.local.config.environment.EnvironmentConfigStorage
import com.tangem.datasource.local.visa.TangemPayStorage
import com.tangem.domain.models.wallet.UserWalletId
@@ -33,7 +31,7 @@ private const val TAG = "TangemPayRequestPerformer"
@Singleton
internal class TangemPayRequestPerformer @Inject constructor(
- @NetworkMoshi moshi: Moshi,
+ private val errorConverter: TangemPayErrorConverter,
private val environmentConfigStorage: EnvironmentConfigStorage,
private val dispatchers: CoroutineDispatcherProvider,
private val tangemPayAuthApi: TangemPayAuthApi,
@@ -42,7 +40,6 @@ internal class TangemPayRequestPerformer @Inject constructor(
private val customerWalletAddresses = ConcurrentHashMap()
private val tokensMutex = Mutex()
- private val errorConverter = TangemPayErrorConverter(moshi)
@Deprecated("Do not use this method")
suspend fun runWithErrorLogs(tag: String, requestBlock: suspend () -> T): Either {
diff --git a/data/visa/src/main/kotlin/com/tangem/data/pay/util/TangemPayErrorConverter.kt b/data/visa/src/main/kotlin/com/tangem/data/pay/util/TangemPayErrorConverter.kt
index 145269f0f5..8080f3b642 100644
--- a/data/visa/src/main/kotlin/com/tangem/data/pay/util/TangemPayErrorConverter.kt
+++ b/data/visa/src/main/kotlin/com/tangem/data/pay/util/TangemPayErrorConverter.kt
@@ -3,10 +3,16 @@ package com.tangem.data.pay.util
import com.squareup.moshi.Moshi
import com.tangem.datasource.api.common.response.ApiResponseError
import com.tangem.datasource.api.pay.models.response.VisaErrorResponse
+import com.tangem.datasource.di.NetworkMoshi
import com.tangem.domain.visa.error.VisaApiError
import com.tangem.utils.converter.Converter
+import javax.inject.Inject
+import javax.inject.Singleton
-class TangemPayErrorConverter(moshi: Moshi) : Converter {
+@Singleton
+internal class TangemPayErrorConverter @Inject constructor(
+ @NetworkMoshi moshi: Moshi,
+) : Converter {
private val visaErrorAdapter by lazy { moshi.adapter(VisaErrorResponse::class.java) }
diff --git a/domain/feedback/models/src/main/kotlin/com/tangem/domain/feedback/models/FeedbackEmailType.kt b/domain/feedback/models/src/main/kotlin/com/tangem/domain/feedback/models/FeedbackEmailType.kt
index 78848710c5..520f49e395 100644
--- a/domain/feedback/models/src/main/kotlin/com/tangem/domain/feedback/models/FeedbackEmailType.kt
+++ b/domain/feedback/models/src/main/kotlin/com/tangem/domain/feedback/models/FeedbackEmailType.kt
@@ -57,7 +57,6 @@ sealed interface FeedbackEmailType {
}
sealed class Visa : FeedbackEmailType {
- data class FailedIssueCard(override val walletMetaInfo: WalletMetaInfo) : Visa()
data class DirectUserRequest(override val walletMetaInfo: WalletMetaInfo) : Visa()
@@ -68,6 +67,8 @@ sealed interface FeedbackEmailType {
override val walletMetaInfo: WalletMetaInfo,
) : Visa()
+ data class FailedIssueCard(override val walletMetaInfo: WalletMetaInfo) : Visa()
+
data class DisputeV2(
val item: TangemPayTxHistoryItem,
override val walletMetaInfo: WalletMetaInfo,
diff --git a/domain/feedback/src/main/java/com/tangem/domain/feedback/FeedbackDataBuilder.kt b/domain/feedback/src/main/java/com/tangem/domain/feedback/FeedbackDataBuilder.kt
index 9a3a7de9b6..00815bea99 100644
--- a/domain/feedback/src/main/java/com/tangem/domain/feedback/FeedbackDataBuilder.kt
+++ b/domain/feedback/src/main/java/com/tangem/domain/feedback/FeedbackDataBuilder.kt
@@ -12,6 +12,7 @@ internal class FeedbackDataBuilder {
fun addTangemPayTxInfo(item: TangemPayTxHistoryItem) {
builder.append(item.jsonRepresentation)
+ builder.breakLine()
}
fun addVisaTxInfo(txDetails: VisaTxDetails) {
@@ -108,6 +109,26 @@ internal class FeedbackDataBuilder {
builder.appendKeyValue("App version", phoneInfo.appVersion)
}
+ fun addTangemPayIssueType(type: FeedbackEmailType.Visa) {
+ val issueType = when (type) {
+ is FeedbackEmailType.Visa.Activation,
+ is FeedbackEmailType.Visa.DirectUserRequest,
+ is FeedbackEmailType.Visa.Dispute,
+ is FeedbackEmailType.Visa.FeatureIsBeta,
+ is FeedbackEmailType.Visa.Withdrawal,
+ -> return
+ is FeedbackEmailType.Visa.DisputeV2 -> when (type.item) {
+ is TangemPayTxHistoryItem.Collateral -> "Receive/Withdraw"
+ is TangemPayTxHistoryItem.Fee,
+ is TangemPayTxHistoryItem.Spend,
+ is TangemPayTxHistoryItem.Payment,
+ -> "Transaction"
+ }
+ is FeedbackEmailType.Visa.FailedIssueCard -> "Card issuing"
+ }
+ builder.appendKeyValue("Issue type", issueType)
+ }
+
fun addBlockchainError(info: BlockchainInfo, error: BlockchainErrorInfo) {
builder.appendKeyValue("Blockchain", info.blockchain)
builder.appendAddresses(
diff --git a/domain/feedback/src/main/java/com/tangem/domain/feedback/SendFeedbackEmailUseCase.kt b/domain/feedback/src/main/java/com/tangem/domain/feedback/SendFeedbackEmailUseCase.kt
index adc8353252..07e0eb137e 100644
--- a/domain/feedback/src/main/java/com/tangem/domain/feedback/SendFeedbackEmailUseCase.kt
+++ b/domain/feedback/src/main/java/com/tangem/domain/feedback/SendFeedbackEmailUseCase.kt
@@ -6,6 +6,9 @@ import com.tangem.domain.feedback.models.FeedbackEmail
import com.tangem.domain.feedback.models.FeedbackEmailType
import com.tangem.domain.feedback.repository.FeedbackRepository
import com.tangem.domain.feedback.utils.*
+import java.io.File
+
+private const val BINDER_MAX_SIZE_BYTES = 500_000 // Safe limit under Android's 1MB Binder limit
/**
* Get email with feedback for support
@@ -29,22 +32,30 @@ class SendFeedbackEmailUseCase(
address = getAddress(type),
subject = emailSubjectResolver.resolve(type),
message = createMessage(type),
- file = feedbackRepository.getZipLogFile(),
+ file = getFile(type),
)
feedbackRepository.sendEmail(email)
}
+ private suspend fun getFile(type: FeedbackEmailType): File? {
+ return if (type.isVisaEmail()) {
+ null
+ } else {
+ feedbackRepository.getZipLogFile()
+ }
+ }
+
private fun getAddress(type: FeedbackEmailType): String {
return when {
- type is FeedbackEmailType.Visa || type.walletMetaInfo?.isVisa == true -> TANGEM_VISA_SUPPORT_EMAIL
+ type.isVisaEmail() -> TANGEM_VISA_SUPPORT_EMAIL
type.walletMetaInfo?.isStart2Coin == true -> START2COIN_SUPPORT_EMAIL
else -> TANGEM_SUPPORT_EMAIL
}
}
private suspend fun createMessage(type: FeedbackEmailType): String {
- return StringBuilder().apply {
+ val fullMessage = buildString {
val title = emailMessageTitleResolver.resolve(type)
append(title)
@@ -54,7 +65,25 @@ class SendFeedbackEmailUseCase(
val body = emailMessageBodyResolver.resolve(type)
append(body)
- }.toString()
+ }
+
+ return truncateMessageIfNeeded(fullMessage)
+ }
+
+ private fun truncateMessageIfNeeded(message: String): String {
+ val messageBytes = message.toByteArray(Charsets.UTF_8)
+
+ return if (messageBytes.size > BINDER_MAX_SIZE_BYTES) {
+ // Find a safe truncation point (avoid cutting in middle of UTF-8 chars)
+ val truncatedBytes = messageBytes.sliceArray(0 until BINDER_MAX_SIZE_BYTES)
+ String(truncatedBytes, Charsets.UTF_8)
+ } else {
+ message
+ }
+ }
+
+ private fun FeedbackEmailType.isVisaEmail(): Boolean {
+ return this is FeedbackEmailType.Visa || this.walletMetaInfo?.isVisa == true
}
private fun StringBuilder.appendDisclaimerIfNeeded(type: FeedbackEmailType): StringBuilder {
diff --git a/domain/feedback/src/main/java/com/tangem/domain/feedback/utils/EmailMessageBodyResolver.kt b/domain/feedback/src/main/java/com/tangem/domain/feedback/utils/EmailMessageBodyResolver.kt
index c8a13a4ef7..1e4ca44bd2 100644
--- a/domain/feedback/src/main/java/com/tangem/domain/feedback/utils/EmailMessageBodyResolver.kt
+++ b/domain/feedback/src/main/java/com/tangem/domain/feedback/utils/EmailMessageBodyResolver.kt
@@ -4,7 +4,6 @@ import com.tangem.domain.feedback.FeedbackDataBuilder
import com.tangem.domain.feedback.models.FeedbackEmailType
import com.tangem.domain.feedback.models.WalletMetaInfo
import com.tangem.domain.feedback.repository.FeedbackRepository
-import com.tangem.domain.visa.model.TangemPayTxHistoryItem
import com.tangem.domain.visa.model.VisaTxDetails
/**
@@ -34,31 +33,39 @@ internal class EmailMessageBodyResolver(
-> addPhoneInfoBody()
is FeedbackEmailType.Visa.Activation -> addUserRequestBody(type.walletMetaInfo)
is FeedbackEmailType.Visa.DirectUserRequest -> addUserRequestBody(type.walletMetaInfo)
- is FeedbackEmailType.Visa.FailedIssueCard -> addUserRequestBody(type.walletMetaInfo)
is FeedbackEmailType.Visa.Dispute -> addVisaRequestBody(type.walletMetaInfo, type.visaTxDetails)
- is FeedbackEmailType.Visa.DisputeV2 -> addTangemPayRequestBody(type.walletMetaInfo, type.item)
+ is FeedbackEmailType.Visa.FailedIssueCard -> addTangemPayFailedIssuingCardBody(type)
+ is FeedbackEmailType.Visa.DisputeV2 -> addTangemPayDisputeRequestBody(type)
is FeedbackEmailType.Visa.Withdrawal -> addTangemPayWithdrawalRequestBody(type)
- is FeedbackEmailType.Visa.FeatureIsBeta -> addTangemPayBetaRequestBody(type.walletMetaInfo)
+ is FeedbackEmailType.Visa.FeatureIsBeta -> addTangemPayBetaRequestBody(type)
}
return build()
}
- private suspend fun FeedbackDataBuilder.addTangemPayRequestBody(
- walletMetaInfo: WalletMetaInfo,
- item: TangemPayTxHistoryItem,
- ) {
- addUserRequestBody(walletMetaInfo)
+ private fun FeedbackDataBuilder.addTangemPayFailedIssuingCardBody(type: FeedbackEmailType.Visa.FailedIssueCard) {
+ addTangemPayPhoneInfoBody(type)
addDelimiter()
- addTangemPayTxInfo(item)
+ type.walletMetaInfo.userWalletId?.let { userWalletId ->
+ addUserWalletId(userWalletId = userWalletId.stringValue)
+ }
}
- private fun FeedbackDataBuilder.addTangemPayBetaRequestBody(walletMetaInfo: WalletMetaInfo) {
- addPhoneInfoBody()
+ private fun FeedbackDataBuilder.addTangemPayDisputeRequestBody(type: FeedbackEmailType.Visa.DisputeV2) {
+ addTangemPayPhoneInfoBody(type = type)
addDelimiter()
- walletMetaInfo.userWalletId?.let { userWalletId ->
+ addTangemPayTxInfo(type.item)
+ addDelimiter()
+ type.walletMetaInfo.userWalletId?.let { userWalletId ->
+ addUserWalletId(userWalletId = userWalletId.stringValue)
+ }
+ }
+
+ private fun FeedbackDataBuilder.addTangemPayBetaRequestBody(type: FeedbackEmailType.Visa) {
+ addTangemPayPhoneInfoBody(type)
+ addDelimiter()
+ type.walletMetaInfo?.userWalletId?.let { userWalletId ->
addUserWalletId(userWalletId = userWalletId.stringValue)
- addDelimiter()
}
}
@@ -122,6 +129,11 @@ internal class EmailMessageBodyResolver(
addPhoneInfo(phoneInfo = feedbackRepository.getPhoneInfo())
}
+ private fun FeedbackDataBuilder.addTangemPayPhoneInfoBody(type: FeedbackEmailType.Visa) {
+ addPhoneInfo(phoneInfo = feedbackRepository.getPhoneInfo())
+ addTangemPayIssueType(type)
+ }
+
private suspend fun FeedbackDataBuilder.addTransactionSendingProblemBody(walletMetaInfo: WalletMetaInfo) {
addUserWalletMetaInfo(walletMetaInfo)
addDelimiter()
diff --git a/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapModel.kt b/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapModel.kt
index ffa4642c46..d227b21dfd 100644
--- a/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapModel.kt
+++ b/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapModel.kt
@@ -1647,8 +1647,7 @@ internal class SwapModel @Inject constructor(
private fun onTangemPaySupportClick(txId: String?) {
modelScope.launch {
- val metaInfo = getWalletMetaInfoUseCase(userWallet.walletId)
- .getOrElse { error("CardInfo must be not null") }
+ val metaInfo = getWalletMetaInfoUseCase(userWallet.walletId).getOrNull() ?: return@launch
val email = FeedbackEmailType.Visa.Withdrawal(
walletMetaInfo = metaInfo,
providerName = dataState.selectedProvider?.name.orEmpty(),
diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayTxHistoryDetailsModel.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayTxHistoryDetailsModel.kt
index 02fd1df5b7..8dae2f4f77 100644
--- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayTxHistoryDetailsModel.kt
+++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayTxHistoryDetailsModel.kt
@@ -9,8 +9,6 @@ import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
import com.tangem.domain.feedback.GetWalletMetaInfoUseCase
import com.tangem.domain.feedback.SendFeedbackEmailUseCase
import com.tangem.domain.feedback.models.FeedbackEmailType
-import com.tangem.domain.models.wallet.requireColdWallet
-import com.tangem.domain.wallets.usecase.GetWalletsUseCase
import com.tangem.features.tangempay.components.txHistory.TangemPayTxHistoryDetailsComponent
import com.tangem.features.tangempay.entity.TangemPayTxHistoryDetailsUM
import com.tangem.features.tangempay.model.transformers.TangemPayTxHistoryDetailsConverter
@@ -21,10 +19,8 @@ import javax.inject.Inject
@Stable
@ModelScoped
-@Suppress("LongParameterList")
internal class TangemPayTxHistoryDetailsModel @Inject constructor(
override val dispatchers: CoroutineDispatcherProvider,
- private val getUserWalletsUseCase: GetWalletsUseCase,
private val getWalletMetaInfoUseCase: GetWalletMetaInfoUseCase,
private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase,
private val urlOpener: UrlOpener,
@@ -66,12 +62,7 @@ internal class TangemPayTxHistoryDetailsModel @Inject constructor(
private fun dispute() {
modelScope.launch {
- val userWalletId = params.userWalletId
- val userWallet = getUserWalletsUseCase.invokeSync()
- .firstOrNull { it.walletId == userWalletId } ?: return@launch
- val walletMetaInfo = getWalletMetaInfoUseCase.invoke(
- userWallet.requireColdWallet().scanResponse,
- ).getOrNull() ?: return@launch
+ val walletMetaInfo = getWalletMetaInfoUseCase.invoke(params.userWalletId).getOrNull() ?: return@launch
sendFeedbackEmailUseCase.invoke(
FeedbackEmailType.Visa.DisputeV2(
diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangempayTxDetailsUi.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangempayTxDetailsUi.kt
index 4e280d9cb7..c406c83696 100644
--- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangempayTxDetailsUi.kt
+++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangempayTxDetailsUi.kt
@@ -6,6 +6,7 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Devices
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
@@ -74,6 +75,7 @@ internal fun TangemPayTxHistoryDetailsContent(state: TangemPayTxHistoryDetailsUM
text = state.transactionSubtitle.resolveReference(),
style = TangemTheme.typography.body2,
color = TangemTheme.colors.text.tertiary,
+ textAlign = TextAlign.Center,
)
Text(
modifier = Modifier.padding(top = 8.dp),
@@ -84,7 +86,7 @@ internal fun TangemPayTxHistoryDetailsContent(state: TangemPayTxHistoryDetailsUM
state.localTransactionText?.let { localTransaction ->
Text(
modifier = Modifier.padding(top = 4.dp),
- text = localTransaction,
+ text = localTransaction.orMaskWithStars(state.isBalanceHidden),
style = TangemTheme.typography.body2,
color = TangemTheme.colors.text.tertiary,
)
@@ -207,11 +209,11 @@ private class TangemPayTxHistoryDetailsUMProvider : CollectionPreviewParameterPr
dismiss = {},
),
TangemPayTxHistoryDetailsUM(
- isBalanceHidden = false,
+ isBalanceHidden = true,
title = stringReference("12 June • 12:40"),
iconState = ImageReference.Res(R.drawable.ic_category_24),
transactionTitle = stringReference("Starbucks"),
- transactionSubtitle = stringReference("Food and drinks"),
+ transactionSubtitle = stringReference("Food and drinks Food and drinks Food and drinks Food and drinks"),
transactionAmount = "-$5.86",
transactionAmountColor = themedColor { TangemTheme.colors.text.primary1 },
localTransactionText = "€ 5.36",
diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/TangemPayClickIntents.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/TangemPayClickIntents.kt
index 332b9c24af..a844424033 100644
--- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/TangemPayClickIntents.kt
+++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/TangemPayClickIntents.kt
@@ -10,11 +10,9 @@ import com.tangem.domain.feedback.GetWalletMetaInfoUseCase
import com.tangem.domain.feedback.SendFeedbackEmailUseCase
import com.tangem.domain.feedback.models.FeedbackEmailType
import com.tangem.domain.models.wallet.UserWalletId
-import com.tangem.domain.models.wallet.requireColdWallet
import com.tangem.domain.pay.repository.OnboardingRepository
import com.tangem.domain.pay.usecase.ProduceTangemPayInitialDataUseCase
import com.tangem.domain.pay.usecase.TangemPayMainScreenCustomerInfoUseCase
-import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController
import com.tangem.features.tangempay.TangemPayFeatureToggles
import kotlinx.coroutines.launch
@@ -41,7 +39,6 @@ internal class TangemPayClickIntentsImplementor @Inject constructor(
private val onboardingRepository: OnboardingRepository,
private val produceInitialDataTangemPay: ProduceTangemPayInitialDataUseCase,
private val getWalletMetainfoUseCase: GetWalletMetaInfoUseCase,
- private val getUserWalletUseCase: GetUserWalletUseCase,
private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase,
private val tangemPayMainScreenCustomerInfoUseCase: TangemPayMainScreenCustomerInfoUseCase,
private val uiMessageSender: UiMessageSender,
@@ -93,7 +90,7 @@ internal class TangemPayClickIntentsImplementor @Inject constructor(
body = resourceReference(R.string.tangempay_failed_to_issue_card_support_description)
}
secondaryButton {
- text = resourceReference(R.string.common_contact_support)
+ text = resourceReference(R.string.tangempay_go_to_support)
onClick {
onPaySupportClick()
closeBs()
@@ -106,10 +103,8 @@ internal class TangemPayClickIntentsImplementor @Inject constructor(
override fun onPaySupportClick() {
modelScope.launch {
- val userWalletId = stateHolder.getSelectedWalletId()
- val userWallet = getUserWalletUseCase.invoke(userWalletId).getOrNull() ?: return@launch
val cardInfo = getWalletMetainfoUseCase.invoke(
- userWallet.requireColdWallet().scanResponse,
+ userWalletId = stateHolder.getSelectedWalletId(),
).getOrNull() ?: return@launch
sendFeedbackEmailUseCase(