Updated on 2026-08-14
This commit is contained in:
parent
4be3782a0a
commit
2ea3f2ca9d
11 changed files with 98 additions and 8 deletions
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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<SwapStatusDTO>(
|
||||
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<SwapTransactionListDTO>.updateList(
|
||||
userWalletId: UserWalletId,
|
||||
fromCryptoCurrency: CryptoCurrency,
|
||||
toCryptoCurrency: CryptoCurrency,
|
||||
fromAccount: Account.CryptoPortfolio?,
|
||||
toAccount: Account.CryptoPortfolio?,
|
||||
transactions: List<SwapTransactionDTO>,
|
||||
): List<SwapTransactionListDTO> {
|
||||
return addOrReplace(
|
||||
|
|
@ -232,6 +253,8 @@ internal class DefaultSwapTransactionRepository(
|
|||
userWalletId = userWalletId,
|
||||
fromCryptoCurrency = fromCryptoCurrency,
|
||||
toCryptoCurrency = toCryptoCurrency,
|
||||
fromAccount = fromAccount,
|
||||
toAccount = toAccount,
|
||||
tokenTransactions = transactions,
|
||||
),
|
||||
predicate = {
|
||||
|
|
|
|||
|
|
@ -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<String, SwapStatusDTO>,
|
||||
multiAccountList: List<AccountList>,
|
||||
): 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<SwapTransactionDTO>,
|
||||
) = 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<AccountList>,
|
||||
derivationIndex: DerivationIndex?,
|
||||
): Account.CryptoPortfolio? {
|
||||
if (derivationIndex == null) return null
|
||||
|
||||
return multiAccountList.asSequence().firstNotNullOfOrNull { accountList ->
|
||||
accountList.accounts.asSequence().filterIsInstance<Account.CryptoPortfolio>()
|
||||
.firstOrNull { it.derivationIndex == derivationIndex }
|
||||
}
|
||||
}
|
||||
|
||||
private fun UserTokensResponse.Token.getDerivationIndex(): DerivationIndex? {
|
||||
return accountId?.toIntOrNull()?.let { DerivationIndex(it).getOrNull() }
|
||||
}
|
||||
}
|
||||
|
|
@ -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,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<SwapTransactionModel>,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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?,
|
||||
)
|
||||
|
|
@ -135,6 +135,7 @@ internal class SendWithSwapConfirmModel @Inject constructor(
|
|||
onDirect = { secondaryCurrencyStatus },
|
||||
onReverse = { primaryCurrencyStatus },
|
||||
),
|
||||
fromAccount = params.accountFlow.value,
|
||||
quote = amountUM?.selectedQuote,
|
||||
rateType = amountUM?.swapRateType,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue