From c8a181c829601ac4b4e4b60e910508ee45fd4496 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 30 Jul 2025 12:29:05 +0500 Subject: [PATCH] Updated on 2026-08-14 --- .../swap/DefaultSwapTransactionRepository.kt | 57 +++++++++---------- .../transaction/SavedSwapStatusConverter.kt | 6 +- .../SavedSwapTransactionConverter.kt | 17 +++++- .../swap/models/SwapTransactionListDTO.kt | 5 +- .../tangem/data/swap/models/SwapTxTypeDTO.kt | 13 +++++ .../swap/models/SwapTransactionListModel.kt | 1 + .../tangem/domain/swap/models/SwapTxType.kt | 6 ++ .../domain/swap/SwapTransactionRepository.kt | 6 +- .../usecase/SwapTransactionSentUseCase.kt | 24 ++++---- .../confirm/model/SwapTransactionSender.kt | 2 + .../swap/DefaultSwapTransactionRepository.kt | 32 ++++++++--- .../SavedSwapTransactionListConverter.kt | 25 ++++---- .../domain/SavedSwapTransactionListModel.kt | 14 ++++- 13 files changed, 135 insertions(+), 73 deletions(-) create mode 100644 data/swap/src/main/java/com/tangem/data/swap/models/SwapTxTypeDTO.kt create mode 100644 domain/swap/models/src/main/java/com/tangem/domain/swap/models/SwapTxType.kt diff --git a/data/swap/src/main/java/com/tangem/data/swap/DefaultSwapTransactionRepository.kt b/data/swap/src/main/java/com/tangem/data/swap/DefaultSwapTransactionRepository.kt index c2d3527060..072cf92212 100644 --- a/data/swap/src/main/java/com/tangem/data/swap/DefaultSwapTransactionRepository.kt +++ b/data/swap/src/main/java/com/tangem/data/swap/DefaultSwapTransactionRepository.kt @@ -13,7 +13,7 @@ import com.tangem.datasource.local.preferences.AppPreferencesStore import com.tangem.datasource.local.preferences.PreferencesKeys import com.tangem.datasource.local.preferences.utils.getObjectList import com.tangem.datasource.local.preferences.utils.getObjectListSync -import com.tangem.datasource.local.preferences.utils.getObjectMapSync +import com.tangem.datasource.local.preferences.utils.getObjectMap import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.models.wallet.UserWalletId @@ -24,9 +24,8 @@ import com.tangem.domain.swap.models.SwapTransactionModel import com.tangem.utils.coroutines.CoroutineDispatcherProvider import com.tangem.utils.extensions.addOrReplace import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.flowOn -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.withContext internal class DefaultSwapTransactionRepository( private val appPreferencesStore: AppPreferencesStore, @@ -95,36 +94,34 @@ internal class DefaultSwapTransactionRepository( } } - override suspend fun getTransactions( + override fun getTransactions( userWallet: UserWallet, cryptoCurrencyId: CryptoCurrency.ID, - ): Flow?> { - return withContext(dispatchers.io) { - val txStatuses = appPreferencesStore.getObjectMapSync( - key = PreferencesKeys.SWAP_TRANSACTIONS_STATUSES_KEY, - ) - appPreferencesStore.getObjectList( - key = PreferencesKeys.SWAP_TRANSACTIONS_KEY, - ).map { savedTransactions -> - val currencyTxs = savedTransactions - ?.filter { - it.userWalletId == userWallet.walletId.stringValue && - ( - it.toCryptoCurrencyId == cryptoCurrencyId.value || - it.fromCryptoCurrencyId == cryptoCurrencyId.value - ) - } + ): Flow?> = combine( + flow = appPreferencesStore.getObjectList( + key = PreferencesKeys.SWAP_TRANSACTIONS_KEY, + ), + flow2 = appPreferencesStore.getObjectMap( + key = PreferencesKeys.SWAP_TRANSACTIONS_STATUSES_KEY, + ), + ) { savedTransactions, txStatuses -> + val currencyTxs = savedTransactions + ?.filter { + it.userWalletId == userWallet.walletId.stringValue && + ( + it.toCryptoCurrencyId == cryptoCurrencyId.value || + it.fromCryptoCurrencyId == cryptoCurrencyId.value + ) + } - currencyTxs?.mapNotNull { - listConverter.convertBack( - value = it, - userWallet = userWallet, - txStatuses = txStatuses, - ) - } - }.flowOn(dispatchers.io) + currencyTxs?.mapNotNull { + listConverter.convertBack( + value = it, + userWallet = userWallet, + txStatuses = txStatuses, + ) } - } + }.flowOn(dispatchers.default) override suspend fun removeTransaction( userWalletId: UserWalletId, @@ -188,7 +185,7 @@ internal class DefaultSwapTransactionRepository( ) val updatesMap = savedMap.toMutableMap() - updatesMap[txId] = savedStatusConverter.convertBack( + updatesMap[txId] = savedStatusConverter.convert( status.copy( refundTokensResponse = refundTokenCurrency?.let { userTokensResponseFactory.createResponseToken(refundTokenCurrency) diff --git a/data/swap/src/main/java/com/tangem/data/swap/converter/transaction/SavedSwapStatusConverter.kt b/data/swap/src/main/java/com/tangem/data/swap/converter/transaction/SavedSwapStatusConverter.kt index c3d8f36903..20c6016104 100644 --- a/data/swap/src/main/java/com/tangem/data/swap/converter/transaction/SavedSwapStatusConverter.kt +++ b/data/swap/src/main/java/com/tangem/data/swap/converter/transaction/SavedSwapStatusConverter.kt @@ -6,9 +6,9 @@ import com.tangem.domain.swap.models.SwapStatus import com.tangem.domain.swap.models.SwapStatusModel import com.tangem.utils.converter.TwoWayConverter -internal class SavedSwapStatusConverter : TwoWayConverter { +internal class SavedSwapStatusConverter : TwoWayConverter { - override fun convert(value: SwapStatusDTO) = SwapStatusModel( + override fun convertBack(value: SwapStatusDTO) = SwapStatusModel( providerId = value.providerId, status = SwapStatus.entries.firstOrNull { it.name.lowercase() == value.status?.name?.lowercase() @@ -22,7 +22,7 @@ internal class SavedSwapStatusConverter : TwoWayConverter?> diff --git a/domain/swap/src/main/java/com/tangem/domain/swap/usecase/SwapTransactionSentUseCase.kt b/domain/swap/src/main/java/com/tangem/domain/swap/usecase/SwapTransactionSentUseCase.kt index 5cebffc055..8d6869366a 100644 --- a/domain/swap/src/main/java/com/tangem/domain/swap/usecase/SwapTransactionSentUseCase.kt +++ b/domain/swap/src/main/java/com/tangem/domain/swap/usecase/SwapTransactionSentUseCase.kt @@ -8,10 +8,7 @@ import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.swap.SwapErrorResolver import com.tangem.domain.swap.SwapRepositoryV2 import com.tangem.domain.swap.SwapTransactionRepository -import com.tangem.domain.swap.models.SwapDataTransactionModel -import com.tangem.domain.swap.models.SwapStatus -import com.tangem.domain.swap.models.SwapStatusModel -import com.tangem.domain.swap.models.SwapTransactionModel +import com.tangem.domain.swap.models.* @Suppress("LongParameterList") class SwapTransactionSentUseCase( @@ -28,15 +25,8 @@ class SwapTransactionSentUseCase( provider: ExpressProvider, txHash: String, timestamp: Long, + swapTxType: SwapTxType, ) = Either.catch { - swapRepositoryV2.swapTransactionSent( - userWallet = userWallet, - fromCryptoCurrencyStatus = fromCryptoCurrencyStatus, - toAddress = swapDataTransactionModel.txTo, - txId = swapDataTransactionModel.txId, - txHash = txHash, - txExtraId = swapDataTransactionModel.txExtraId, - ) if (provider.type.shouldStoreSwapTransaction()) { swapTransactionRepository.storeTransaction( userWalletId = userWallet.walletId, @@ -56,12 +46,22 @@ class SwapTransactionSentUseCase( txExternalId = (swapDataTransactionModel as? SwapDataTransactionModel.CEX)?.externalTxId, averageDuration = null, ), + swapTxType = swapTxType, ), ) } + swapTransactionRepository.storeLastSwappedCryptoCurrencyId( userWalletId = userWallet.walletId, cryptoCurrencyId = toCryptoCurrencyStatus.currency.id, ) + swapRepositoryV2.swapTransactionSent( + userWallet = userWallet, + fromCryptoCurrencyStatus = fromCryptoCurrencyStatus, + toAddress = swapDataTransactionModel.txTo, + txId = swapDataTransactionModel.txId, + txHash = txHash, + txExtraId = swapDataTransactionModel.txExtraId, + ) }.mapLeft(swapErrorResolver::resolve) } \ No newline at end of file diff --git a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/confirm/model/SwapTransactionSender.kt b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/confirm/model/SwapTransactionSender.kt index f6c595b273..458d1ebd4e 100644 --- a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/confirm/model/SwapTransactionSender.kt +++ b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/confirm/model/SwapTransactionSender.kt @@ -9,6 +9,7 @@ import com.tangem.domain.models.currency.CryptoCurrencyStatus import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.swap.models.SwapDataModel import com.tangem.domain.swap.models.SwapDataTransactionModel +import com.tangem.domain.swap.models.SwapTxType import com.tangem.domain.swap.usecase.GetSwapDataUseCase import com.tangem.domain.swap.usecase.SwapTransactionSentUseCase import com.tangem.domain.transaction.error.SendTransactionError @@ -158,6 +159,7 @@ internal class SwapTransactionSender @AssistedInject constructor( provider = provider, txHash = txHash, timestamp = timestamp, + swapTxType = SwapTxType.SendWithSwap, ) onSendSuccess(txHash, timestamp, swapData) }, diff --git a/features/swap/data/src/main/java/com/tangem/feature/swap/DefaultSwapTransactionRepository.kt b/features/swap/data/src/main/java/com/tangem/feature/swap/DefaultSwapTransactionRepository.kt index e5c25f522c..d4fec5e8ed 100644 --- a/features/swap/data/src/main/java/com/tangem/feature/swap/DefaultSwapTransactionRepository.kt +++ b/features/swap/data/src/main/java/com/tangem/feature/swap/DefaultSwapTransactionRepository.kt @@ -92,21 +92,37 @@ internal class DefaultSwapTransactionRepository( key = PreferencesKeys.SWAP_TRANSACTIONS_STATUSES_KEY, ), ) { savedTransactions, txStatuses -> - val currencyTxs = savedTransactions?.filter { - it.userWalletId == userWallet.walletId.stringValue && - ( - it.toCryptoCurrencyId == cryptoCurrencyId.value || - it.fromCryptoCurrencyId == cryptoCurrencyId.value - ) + + val currencyToTxs = savedTransactions?.filter { + val isUserWallet = it.userWalletId == userWallet.walletId.stringValue + val toCurrency = it.toCryptoCurrencyId == cryptoCurrencyId.value + isUserWallet && toCurrency } - currencyTxs?.mapNotNull { + val currencyFromTxs = savedTransactions?.filter { + val isUserWallet = it.userWalletId == userWallet.walletId.stringValue + val fromCurrency = it.fromCryptoCurrencyId == cryptoCurrencyId.value + isUserWallet && fromCurrency + } + + val toTxs = currencyToTxs?.mapNotNull { + converter.convertBack( + value = it, + userWallet = userWallet, + txStatuses = txStatuses, + onFilter = { it.swapTxTypeDTO == SwapTxTypeDTO.Swap }, + ) + }.orEmpty() + + val fromTxs = currencyFromTxs?.mapNotNull { converter.convertBack( value = it, userWallet = userWallet, txStatuses = txStatuses, ) - } + }.orEmpty() + + fromTxs + toTxs } .flowOn(dispatchers.default) } diff --git a/features/swap/data/src/main/java/com/tangem/feature/swap/converters/SavedSwapTransactionListConverter.kt b/features/swap/data/src/main/java/com/tangem/feature/swap/converters/SavedSwapTransactionListConverter.kt index 4735f63fdc..abef06ede4 100644 --- a/features/swap/data/src/main/java/com/tangem/feature/swap/converters/SavedSwapTransactionListConverter.kt +++ b/features/swap/data/src/main/java/com/tangem/feature/swap/converters/SavedSwapTransactionListConverter.kt @@ -34,6 +34,7 @@ internal class SavedSwapTransactionListConverter( value: SavedSwapTransactionListModelInner, userWallet: UserWallet, txStatuses: Map, + onFilter: (SavedSwapTransactionModel) -> Boolean = { true }, ): SavedSwapTransactionListModel? { val fromToken = value.fromTokensResponse val toToken = value.toTokensResponse @@ -50,17 +51,19 @@ internal class SavedSwapTransactionListConverter( ) ?: return null return SavedSwapTransactionListModel( - transactions = value.transactions.map { tx -> - val status = txStatuses[tx.txId] - val refundCurrency = status?.refundTokensResponse?.let { id -> - responseCryptoCurrenciesFactory.createCurrency( - responseToken = id, - userWallet = userWallet, - ) - } - val statusWithRefundCurrency = status?.copy(refundCurrency = refundCurrency) - tx.copy(status = statusWithRefundCurrency) - }, + transactions = value.transactions + .filter(onFilter) + .map { tx -> + val status = txStatuses[tx.txId] + val refundCurrency = status?.refundTokensResponse?.let { id -> + responseCryptoCurrenciesFactory.createCurrency( + responseToken = id, + userWallet = userWallet, + ) + } + val statusWithRefundCurrency = status?.copy(refundCurrency = refundCurrency) + tx.copy(status = statusWithRefundCurrency) + }, userWalletId = value.userWalletId, fromCryptoCurrencyId = value.fromCryptoCurrencyId, toCryptoCurrencyId = value.toCryptoCurrencyId, diff --git a/features/swap/domain/models/src/main/java/com/tangem/feature/swap/domain/models/domain/SavedSwapTransactionListModel.kt b/features/swap/domain/models/src/main/java/com/tangem/feature/swap/domain/models/domain/SavedSwapTransactionListModel.kt index 68fea21eff..94742cbac9 100644 --- a/features/swap/domain/models/src/main/java/com/tangem/feature/swap/domain/models/domain/SavedSwapTransactionListModel.kt +++ b/features/swap/domain/models/src/main/java/com/tangem/feature/swap/domain/models/domain/SavedSwapTransactionListModel.kt @@ -50,4 +50,16 @@ data class SavedSwapTransactionModel( val provider: SwapProvider, @Json(name = "status") val status: ExchangeStatusModel? = null, -) \ No newline at end of file + @Json(name = "swapTxType") + val swapTxTypeDTO: SwapTxTypeDTO? = SwapTxTypeDTO.Swap, +) + +// TODO refactor to use separate models to store +@JsonClass(generateAdapter = false) +enum class SwapTxTypeDTO { + @Json(name = "Swap") + Swap, + + @Json(name = "SendWithSwap") + SendWithSwap, +} \ No newline at end of file