From 2ea3f2ca9ded8a71b0a98fc2039b7d2a4b631f33 Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 30 Oct 2025 17:38:10 +0500 Subject: [PATCH] Updated on 2026-08-14 --- data/swap/build.gradle.kts | 1 + .../swap/DefaultSwapTransactionRepository.kt | 27 ++++++++++- .../SavedSwapTransactionListConverter.kt | 45 +++++++++++++++++-- .../com/tangem/data/swap/di/SwapDataModule.kt | 6 +++ .../swap/models/SwapTransactionListModel.kt | 3 ++ .../domain/swap/SwapTransactionRepository.kt | 6 +++ .../usecase/SwapTransactionSentUseCase.kt | 5 +++ .../SendDestinationInitialStateTransformer.kt | 2 +- .../swap/v2/impl/common/ConfirmData.kt | 2 + .../confirm/model/SendWithSwapConfirmModel.kt | 1 + .../confirm/model/SwapTransactionSender.kt | 8 +++- 11 files changed, 98 insertions(+), 8 deletions(-) diff --git a/data/swap/build.gradle.kts b/data/swap/build.gradle.kts index f2ff37fff6..78b5b851c7 100644 --- a/data/swap/build.gradle.kts +++ b/data/swap/build.gradle.kts @@ -35,6 +35,7 @@ dependencies { implementation(projects.domain.networks) implementation(projects.domain.staking.models) implementation(projects.domain.staking) + implementation(projects.domain.account) /** Tangem SDK */ implementation(tangemDeps.blockchain) { 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 f7ade3cac9..0e2d2a1a79 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 @@ -15,6 +15,9 @@ 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.getObjectMap +import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles +import com.tangem.domain.account.supplier.MultiAccountListSupplier +import com.tangem.domain.models.account.Account import com.tangem.domain.models.account.AccountId import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.wallet.UserWallet @@ -27,6 +30,7 @@ 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.flowOf import kotlinx.coroutines.flow.flowOn internal class DefaultSwapTransactionRepository( @@ -34,6 +38,8 @@ internal class DefaultSwapTransactionRepository( private val responseCryptoCurrenciesFactory: ResponseCryptoCurrenciesFactory, private val networkFactory: NetworkFactory, private val dispatchers: CoroutineDispatcherProvider, + private val multiAccountListSupplier: MultiAccountListSupplier, + private val accountsFeatureToggles: AccountsFeatureToggles, ) : SwapTransactionRepository { private val listConverter by lazy(LazyThreadSafetyMode.NONE) { @@ -54,13 +60,15 @@ internal class DefaultSwapTransactionRepository( userWalletId: UserWalletId, fromCryptoCurrency: CryptoCurrency, toCryptoCurrency: CryptoCurrency, + fromAccount: Account.CryptoPortfolio?, + toAccount: Account.CryptoPortfolio?, transaction: SwapTransactionModel, ) { transaction.status?.let { storeTransactionState( txId = transaction.txId, status = it, - accountWithCurrency = null, + accountWithCurrency = fromAccount?.accountId to fromCryptoCurrency, ) } appPreferencesStore.editData { mutablePreferences -> @@ -87,12 +95,16 @@ internal class DefaultSwapTransactionRepository( userWalletId = userWalletId, fromCryptoCurrency = fromCryptoCurrency, toCryptoCurrency = toCryptoCurrency, + fromAccount = fromAccount, + toAccount = toAccount, transactions = tokenTransactions, ) ?: listOf( listConverter.default( userWalletId = userWalletId, fromCryptoCurrency = fromCryptoCurrency, toCryptoCurrency = toCryptoCurrency, + fromAccount = fromAccount, + toAccount = toAccount, tokenTransactions = listOf(converter.convert(transaction)), ), ), @@ -110,7 +122,12 @@ internal class DefaultSwapTransactionRepository( flow2 = appPreferencesStore.getObjectMap( key = PreferencesKeys.SWAP_TRANSACTIONS_STATUSES_KEY, ), - ) { savedTransactions, txStatuses -> + flow3 = if (accountsFeatureToggles.isFeatureEnabled) { + multiAccountListSupplier() + } else { + flowOf(emptyList()) + }, + ) { savedTransactions, txStatuses, multiAccountList -> val currencyTxs = savedTransactions ?.filter { it.userWalletId == userWallet.walletId.stringValue && @@ -123,6 +140,7 @@ internal class DefaultSwapTransactionRepository( currencyTxs?.mapNotNull { listConverter.convertBack( value = it, + multiAccountList = multiAccountList, userWallet = userWallet, txStatuses = txStatuses, ) @@ -221,10 +239,13 @@ internal class DefaultSwapTransactionRepository( fromCryptoCurrencyId == fromCurrencyId.value } + @Suppress("LongParameterList") private fun List.updateList( userWalletId: UserWalletId, fromCryptoCurrency: CryptoCurrency, toCryptoCurrency: CryptoCurrency, + fromAccount: Account.CryptoPortfolio?, + toAccount: Account.CryptoPortfolio?, transactions: List, ): List { return addOrReplace( @@ -232,6 +253,8 @@ internal class DefaultSwapTransactionRepository( userWalletId = userWalletId, fromCryptoCurrency = fromCryptoCurrency, toCryptoCurrency = toCryptoCurrency, + fromAccount = fromAccount, + toAccount = toAccount, tokenTransactions = transactions, ), predicate = { diff --git a/data/swap/src/main/java/com/tangem/data/swap/converter/transaction/SavedSwapTransactionListConverter.kt b/data/swap/src/main/java/com/tangem/data/swap/converter/transaction/SavedSwapTransactionListConverter.kt index 16b144b862..9688b3086b 100644 --- a/data/swap/src/main/java/com/tangem/data/swap/converter/transaction/SavedSwapTransactionListConverter.kt +++ b/data/swap/src/main/java/com/tangem/data/swap/converter/transaction/SavedSwapTransactionListConverter.kt @@ -9,6 +9,9 @@ import com.tangem.data.swap.models.SwapStatusDTO import com.tangem.data.swap.models.SwapTransactionDTO import com.tangem.data.swap.models.SwapTransactionListDTO import com.tangem.datasource.api.tangemTech.models.UserTokensResponse +import com.tangem.domain.account.models.AccountList +import com.tangem.domain.models.account.Account +import com.tangem.domain.models.account.DerivationIndex import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.network.Network import com.tangem.domain.models.wallet.UserWallet @@ -32,11 +35,11 @@ internal class SavedSwapTransactionListConverter( toCryptoCurrencyId = value.toCryptoCurrencyId, fromTokensResponse = userTokensResponseFactory.createResponseToken( currency = value.fromCryptoCurrency, - accountId = null, + accountId = value.fromAccount?.accountId, ), toTokensResponse = userTokensResponseFactory.createResponseToken( currency = value.toCryptoCurrency, - accountId = null, + accountId = value.toAccount?.accountId, ), transactions = savedSwapTransactionConverter.convertList(value.transactions), ) @@ -45,9 +48,12 @@ internal class SavedSwapTransactionListConverter( value: SwapTransactionListDTO, userWallet: UserWallet, txStatuses: Map, + multiAccountList: List, ): SwapTransactionListModel? { val fromToken = value.fromTokensResponse val toToken = value.toTokensResponse + val fromDerivationIndex = fromToken?.getDerivationIndex() + val toDerivationIndex = toToken?.getDerivationIndex() return if (fromToken == null || toToken == null) { null } else { @@ -73,14 +79,25 @@ internal class SavedSwapTransactionListConverter( toCryptoCurrencyId = value.toCryptoCurrencyId, fromCryptoCurrency = fromCryptoCurrency, toCryptoCurrency = toCryptoCurrency, + fromAccount = getAccountByDerivationIndex( + multiAccountList = multiAccountList, + derivationIndex = fromDerivationIndex, + ), + toAccount = getAccountByDerivationIndex( + multiAccountList = multiAccountList, + derivationIndex = toDerivationIndex, + ), ) } } + @Suppress("LongParameterList") fun default( userWalletId: UserWalletId, fromCryptoCurrency: CryptoCurrency, toCryptoCurrency: CryptoCurrency, + fromAccount: Account.CryptoPortfolio?, + toAccount: Account.CryptoPortfolio?, tokenTransactions: List, ) = SwapTransactionListDTO( userWalletId = userWalletId.stringValue, @@ -88,9 +105,12 @@ internal class SavedSwapTransactionListConverter( toCryptoCurrencyId = toCryptoCurrency.id.value, fromTokensResponse = userTokensResponseFactory.createResponseToken( currency = fromCryptoCurrency, - accountId = null, + accountId = fromAccount?.accountId, + ), + toTokensResponse = userTokensResponseFactory.createResponseToken( + currency = toCryptoCurrency, + accountId = toAccount?.accountId, ), - toTokensResponse = userTokensResponseFactory.createResponseToken(currency = toCryptoCurrency, accountId = null), transactions = tokenTransactions, ) @@ -108,7 +128,24 @@ internal class SavedSwapTransactionListConverter( blockchain = blockchain, extraDerivationPath = token.derivationPath, userWallet = userWallet, + accountIndex = token.accountId?.toIntOrNull()?.let { DerivationIndex(it).getOrNull() }, ) } } + + private fun getAccountByDerivationIndex( + multiAccountList: List, + derivationIndex: DerivationIndex?, + ): Account.CryptoPortfolio? { + if (derivationIndex == null) return null + + return multiAccountList.asSequence().firstNotNullOfOrNull { accountList -> + accountList.accounts.asSequence().filterIsInstance() + .firstOrNull { it.derivationIndex == derivationIndex } + } + } + + private fun UserTokensResponse.Token.getDerivationIndex(): DerivationIndex? { + return accountId?.toIntOrNull()?.let { DerivationIndex(it).getOrNull() } + } } \ No newline at end of file diff --git a/data/swap/src/main/java/com/tangem/data/swap/di/SwapDataModule.kt b/data/swap/src/main/java/com/tangem/data/swap/di/SwapDataModule.kt index 7784c4ea1b..fd3fadb12b 100644 --- a/data/swap/src/main/java/com/tangem/data/swap/di/SwapDataModule.kt +++ b/data/swap/src/main/java/com/tangem/data/swap/di/SwapDataModule.kt @@ -12,6 +12,8 @@ import com.tangem.datasource.api.express.models.response.ExpressErrorResponse import com.tangem.datasource.crypto.DataSignatureVerifier import com.tangem.datasource.di.NetworkMoshi import com.tangem.datasource.local.preferences.AppPreferencesStore +import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles +import com.tangem.domain.account.supplier.MultiAccountListSupplier import com.tangem.domain.express.ExpressRepository import com.tangem.domain.quotes.single.SingleQuoteStatusFetcher import com.tangem.domain.quotes.single.SingleQuoteStatusSupplier @@ -68,12 +70,16 @@ internal object SwapDataModule { appPreferencesStore: AppPreferencesStore, responseCryptoCurrenciesFactory: ResponseCryptoCurrenciesFactory, networkFactory: NetworkFactory, + multiAccountListSupplier: MultiAccountListSupplier, + accountsFeatureToggles: AccountsFeatureToggles, dispatchers: CoroutineDispatcherProvider, ): SwapTransactionRepository { return DefaultSwapTransactionRepository( appPreferencesStore = appPreferencesStore, responseCryptoCurrenciesFactory = responseCryptoCurrenciesFactory, networkFactory = networkFactory, + multiAccountListSupplier = multiAccountListSupplier, + accountsFeatureToggles = accountsFeatureToggles, dispatchers = dispatchers, ) } diff --git a/domain/swap/models/src/main/java/com/tangem/domain/swap/models/SwapTransactionListModel.kt b/domain/swap/models/src/main/java/com/tangem/domain/swap/models/SwapTransactionListModel.kt index 7bd7a99414..89edac21b3 100644 --- a/domain/swap/models/src/main/java/com/tangem/domain/swap/models/SwapTransactionListModel.kt +++ b/domain/swap/models/src/main/java/com/tangem/domain/swap/models/SwapTransactionListModel.kt @@ -1,6 +1,7 @@ package com.tangem.domain.swap.models import com.tangem.domain.express.models.ExpressProvider +import com.tangem.domain.models.account.Account import com.tangem.domain.models.currency.CryptoCurrency import java.math.BigDecimal @@ -13,6 +14,8 @@ data class SwapTransactionListModel( val toCryptoCurrencyId: String, val fromCryptoCurrency: CryptoCurrency, val toCryptoCurrency: CryptoCurrency, + val fromAccount: Account.CryptoPortfolio?, + val toAccount: Account.CryptoPortfolio?, val transactions: List, ) diff --git a/domain/swap/src/main/java/com/tangem/domain/swap/SwapTransactionRepository.kt b/domain/swap/src/main/java/com/tangem/domain/swap/SwapTransactionRepository.kt index 5f9a18e411..7fe9292ea2 100644 --- a/domain/swap/src/main/java/com/tangem/domain/swap/SwapTransactionRepository.kt +++ b/domain/swap/src/main/java/com/tangem/domain/swap/SwapTransactionRepository.kt @@ -1,5 +1,6 @@ package com.tangem.domain.swap +import com.tangem.domain.models.account.Account import com.tangem.domain.models.account.AccountId import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.wallet.UserWallet @@ -20,12 +21,17 @@ interface SwapTransactionRepository { * @param userWalletId selected user wallet id * @param fromCryptoCurrency currency swap from * @param toCryptoCurrency currency swap to + * @param fromAccount account swap from + * @param toAccount account swap to * @param transaction swap transaction */ + @Suppress("LongParameterList") suspend fun storeTransaction( userWalletId: UserWalletId, fromCryptoCurrency: CryptoCurrency, toCryptoCurrency: CryptoCurrency, + fromAccount: Account.CryptoPortfolio?, + toAccount: Account.CryptoPortfolio?, transaction: SwapTransactionModel, ) 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 8d6869366a..be872f8701 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 @@ -3,6 +3,7 @@ package com.tangem.domain.swap.usecase import arrow.core.Either import com.tangem.domain.express.models.ExpressProvider import com.tangem.domain.express.models.ExpressProviderType.Companion.shouldStoreSwapTransaction +import com.tangem.domain.models.account.Account import com.tangem.domain.models.currency.CryptoCurrencyStatus import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.swap.SwapErrorResolver @@ -21,6 +22,8 @@ class SwapTransactionSentUseCase( userWallet: UserWallet, fromCryptoCurrencyStatus: CryptoCurrencyStatus, toCryptoCurrencyStatus: CryptoCurrencyStatus, + fromAccount: Account.CryptoPortfolio?, + toAccount: Account.CryptoPortfolio?, swapDataTransactionModel: SwapDataTransactionModel, provider: ExpressProvider, txHash: String, @@ -32,6 +35,8 @@ class SwapTransactionSentUseCase( userWalletId = userWallet.walletId, fromCryptoCurrency = fromCryptoCurrencyStatus.currency, toCryptoCurrency = toCryptoCurrencyStatus.currency, + fromAccount = fromAccount, + toAccount = toAccount, transaction = SwapTransactionModel( txId = swapDataTransactionModel.txId, provider = provider, diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/destination/model/transformers/SendDestinationInitialStateTransformer.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/destination/model/transformers/SendDestinationInitialStateTransformer.kt index 151c0d6900..0fc9f3c4a6 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/destination/model/transformers/SendDestinationInitialStateTransformer.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/destination/model/transformers/SendDestinationInitialStateTransformer.kt @@ -6,9 +6,9 @@ import androidx.compose.ui.text.input.KeyboardType import com.tangem.core.ui.extensions.resourceReference import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.network.Network -import com.tangem.features.send.v2.impl.R import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationTextFieldUM import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationUM +import com.tangem.features.send.v2.impl.R import com.tangem.utils.transformer.Transformer internal class SendDestinationInitialStateTransformer( diff --git a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/common/ConfirmData.kt b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/common/ConfirmData.kt index 995f10c9ae..5ce32201dc 100644 --- a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/common/ConfirmData.kt +++ b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/common/ConfirmData.kt @@ -2,6 +2,7 @@ package com.tangem.features.swap.v2.impl.common import com.tangem.blockchain.common.transaction.Fee import com.tangem.domain.express.models.ExpressRateType +import com.tangem.domain.models.account.Account import com.tangem.domain.models.currency.CryptoCurrencyStatus import com.tangem.domain.transaction.error.GetFeeError import com.tangem.features.swap.v2.impl.common.entity.SwapQuoteUM @@ -16,6 +17,7 @@ internal data class ConfirmData( val feeError: GetFeeError?, val fromCryptoCurrencyStatus: CryptoCurrencyStatus?, val toCryptoCurrencyStatus: CryptoCurrencyStatus?, + val fromAccount: Account.CryptoPortfolio?, val quote: SwapQuoteUM?, val rateType: ExpressRateType?, ) \ 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/SendWithSwapConfirmModel.kt b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/confirm/model/SendWithSwapConfirmModel.kt index c4961dabf6..ecbfea1277 100644 --- a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/confirm/model/SendWithSwapConfirmModel.kt +++ b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/confirm/model/SendWithSwapConfirmModel.kt @@ -135,6 +135,7 @@ internal class SendWithSwapConfirmModel @Inject constructor( onDirect = { secondaryCurrencyStatus }, onReverse = { primaryCurrencyStatus }, ), + fromAccount = params.accountFlow.value, quote = amountUM?.selectedQuote, rateType = amountUM?.swapRateType, ) 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 58ed07d518..3602881267 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 @@ -6,6 +6,7 @@ import com.tangem.domain.express.models.ExpressError import com.tangem.domain.express.models.ExpressOperationType import com.tangem.domain.express.models.ExpressProvider import com.tangem.domain.express.models.ExpressProviderType +import com.tangem.domain.models.account.Account import com.tangem.domain.models.currency.CryptoCurrencyStatus import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.swap.models.SwapDataModel @@ -64,7 +65,7 @@ internal class SwapTransactionSender @AssistedInject constructor( } } - suspend fun onCexTransaction( + private suspend fun onCexTransaction( confirmData: ConfirmData, isAmountSubtractAvailable: Boolean, onSendSuccess: (String, Long, SwapDataModel) -> Unit, @@ -74,6 +75,7 @@ internal class SwapTransactionSender @AssistedInject constructor( ) { val fromStatus = confirmData.fromCryptoCurrencyStatus ?: return val toStatus = confirmData.toCryptoCurrencyStatus ?: return + val fromAccount = confirmData.fromAccount val provider = confirmData.quote?.provider ?: return val rateType = confirmData.rateType ?: return val amountValue = confirmData.enteredAmount ?: return @@ -102,6 +104,7 @@ internal class SwapTransactionSender @AssistedInject constructor( createAndSendCexTransaction( fromAmount = fromAmount, fromStatus = fromStatus, + fromAccount = fromAccount, toStatus = toStatus, fee = confirmData.fee, provider = provider, @@ -116,6 +119,7 @@ internal class SwapTransactionSender @AssistedInject constructor( fromAmount: BigDecimal, fromStatus: CryptoCurrencyStatus, toStatus: CryptoCurrencyStatus, + fromAccount: Account.CryptoPortfolio?, fee: Fee, provider: ExpressProvider, swapData: SwapDataModel, @@ -160,6 +164,8 @@ internal class SwapTransactionSender @AssistedInject constructor( userWallet = userWallet, fromCryptoCurrencyStatus = fromStatus, toCryptoCurrencyStatus = toStatus, + fromAccount = fromAccount, + toAccount = null, swapDataTransactionModel = swapTransaction, provider = provider, txHash = txHash,