Updated on 2026-08-14

This commit is contained in:
Tangem 2026-02-11 17:48:20 +05:00
parent 6ed1946ac3
commit aac48015b3
88 changed files with 335 additions and 239 deletions

View file

@ -48,7 +48,6 @@ class AccountPortfolioItemUMConverter(
)
UserWalletItemUM.Information.Loaded(text)
}
is Account.Payment -> TODO("[REDACTED_JIRA]")
}
private fun getImageState(account: Account.CryptoPortfolio) = when (account) {
@ -56,7 +55,6 @@ class AccountPortfolioItemUMConverter(
name = account.accountName.toUM().value,
icon = CryptoPortfolioIconConverter.convert(account.icon),
)
is Account.Payment -> TODO("[REDACTED_JIRA]")
}
private fun getBalanceInfo(): UserWalletItemUM.Balance {

View file

@ -82,7 +82,7 @@ fun PortfolioSelectRow(
@Immutable
data class PortfolioSelectUM(
val icon: AccountIconUM.CryptoPortfolio?,
val icon: AccountIconUM?,
val name: TextReference,
val isAccountMode: Boolean,
val isMultiChoice: Boolean,

View file

@ -1,5 +1,6 @@
package com.tangem.common.ui.amountScreen.converters
import com.tangem.common.ui.account.AccountIconUM
import com.tangem.common.ui.account.AccountTitleUM
import com.tangem.common.ui.account.CryptoPortfolioIconConverter
import com.tangem.common.ui.account.toUM
@ -11,12 +12,12 @@ class AmountAccountConverter(
private val prefixText: TextReference,
private val isAccountsMode: Boolean,
private val walletTitle: TextReference,
) : Converter<Account.CryptoPortfolio?, AccountTitleUM> {
override fun convert(value: Account.CryptoPortfolio?): AccountTitleUM {
) : Converter<Account?, AccountTitleUM> {
override fun convert(value: Account?): AccountTitleUM {
return if (value != null && isAccountsMode) {
AccountTitleUM.Account(
name = value.accountName.toUM().value,
icon = CryptoPortfolioIconConverter.convert(value.icon),
icon = getAccountIcon(account = value),
prefixText = prefixText,
)
} else {
@ -25,4 +26,11 @@ class AmountAccountConverter(
)
}
}
private fun getAccountIcon(account: Account): AccountIconUM {
return when (account) {
is Account.CryptoPortfolio -> CryptoPortfolioIconConverter.convert(account.icon)
is Account.Payment -> AccountIconUM.Payment
}
}
}

View file

@ -33,10 +33,10 @@ internal class DefaultSingleAccountProducer @AssistedInject constructor(
private val dispatchers: CoroutineDispatcherProvider,
) : SingleAccountProducer {
override val fallback: Option<Account.CryptoPortfolio>
override val fallback: Option<Account>
get() = none()
override fun produce(): Flow<Account.CryptoPortfolio> {
override fun produce(): Flow<Account> {
return singleAccountListSupplier(
params = SingleAccountListProducer.Params(userWalletId = params.accountId.userWalletId),
)

View file

@ -19,6 +19,7 @@ import com.tangem.datasource.api.tangemTech.models.account.WalletAccountDTO
import com.tangem.datasource.local.datastore.RuntimeStateStore
import com.tangem.domain.account.models.AccountList
import com.tangem.domain.account.models.ArchivedAccount
import com.tangem.domain.models.account.Account
import com.tangem.domain.models.account.Account.CryptoPortfolio
import com.tangem.domain.models.account.AccountId
import com.tangem.domain.models.account.AccountName

View file

@ -60,8 +60,8 @@ internal class DefaultSwapTransactionRepository(
userWalletId: UserWalletId,
fromCryptoCurrency: CryptoCurrency,
toCryptoCurrency: CryptoCurrency,
fromAccount: Account.CryptoPortfolio?,
toAccount: Account.CryptoPortfolio?,
fromAccount: Account?,
toAccount: Account?,
transaction: SwapTransactionModel,
) {
transaction.status?.let { swapTxList ->
@ -244,8 +244,8 @@ internal class DefaultSwapTransactionRepository(
userWalletId: UserWalletId,
fromCryptoCurrency: CryptoCurrency,
toCryptoCurrency: CryptoCurrency,
fromAccount: Account.CryptoPortfolio?,
toAccount: Account.CryptoPortfolio?,
fromAccount: Account?,
toAccount: Account?,
transactions: List<SwapTransactionDTO>,
): List<SwapTransactionListDTO> {
return addOrReplace(

View file

@ -101,8 +101,8 @@ internal class SavedSwapTransactionListConverter(
userWalletId: UserWalletId,
fromCryptoCurrency: CryptoCurrency,
toCryptoCurrency: CryptoCurrency,
fromAccount: Account.CryptoPortfolio?,
toAccount: Account.CryptoPortfolio?,
fromAccount: Account?,
toAccount: Account?,
tokenTransactions: List<SwapTransactionDTO>,
) = SwapTransactionListDTO(
userWalletId = userWalletId.stringValue,

View file

@ -9,6 +9,7 @@ import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.data.walletconnect.utils.*
import com.tangem.datasource.local.walletconnect.WalletConnectStore
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
import com.tangem.domain.models.account.Account
import com.tangem.domain.models.account.AccountId
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.walletconnect.WcAnalyticEvents
@ -116,7 +117,7 @@ internal class DefaultWcSessionsManager(
val wcSessions = savedPending.plus(inStore).mapNotNull { storeSession ->
val wallet = wallets.find { it.walletId == storeSession.walletId } ?: return@mapNotNull null
val sdkSession = inSdk.find { it.topic == storeSession.topic } ?: return@mapNotNull null
val account = storeSession.accountId?.let { wcNetworksConverter.getAccount(it) }
val account = storeSession.accountId?.let { wcNetworksConverter.getAccount(it) } as? Account.CryptoPortfolio
if (accountsFeatureToggles.isFeatureEnabled && account == null) {
return@mapNotNull null
}

View file

@ -5,7 +5,6 @@ import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.data.walletconnect.sign.SignStateConverter.toPreSign
import com.tangem.data.walletconnect.sign.SignStateConverter.toResult
import com.tangem.data.walletconnect.sign.SignStateConverter.toSigning
import com.tangem.domain.models.account.derivationIndex
import com.tangem.domain.walletconnect.WcAnalyticEvents
import com.tangem.domain.walletconnect.model.WcRequestError
import com.tangem.domain.walletconnect.model.WcRequestError.Companion.code

View file

@ -13,6 +13,7 @@ import com.tangem.domain.account.supplier.SingleAccountSupplier
import com.tangem.domain.models.account.Account
import com.tangem.domain.models.account.AccountId
import com.tangem.domain.models.account.AccountStatus
import com.tangem.domain.models.account.filterCryptoPortfolio
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.network.Network
import com.tangem.domain.models.wallet.UserWallet
@ -146,10 +147,12 @@ internal class WcNetworksConverter @Inject constructor(
.filterIsInstance<CryptoCurrency.Coin>().map(CryptoCurrency.Coin::network)
}
private suspend fun getAccountStatus(accountId: AccountId): AccountStatus? {
private suspend fun getAccountStatus(accountId: AccountId): AccountStatus.CryptoPortfolio? {
return singleAccountStatusListSupplier.getSyncOrNull(
SingleAccountStatusListProducer.Params(accountId.userWalletId),
)?.accountStatuses?.find { it.account.accountId == accountId }
)?.accountStatuses
?.filterCryptoPortfolio()
?.find { it.account.accountId == accountId }
}
suspend fun getAccountNetworks(accountId: AccountId): List<Network> {

View file

@ -5,6 +5,7 @@ import com.tangem.domain.models.TokensGroupType
import com.tangem.domain.models.TokensSortType
import com.tangem.domain.models.TotalFiatBalance
import com.tangem.domain.models.account.AccountStatus
import com.tangem.domain.models.account.filterCryptoPortfolio
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.wallet.UserWalletId
import kotlinx.serialization.Serializable
@ -33,13 +34,16 @@ data class AccountStatusList(
) {
val mainAccount: AccountStatus.CryptoPortfolio
get() = accountStatuses.first { accountStatus ->
when (accountStatus) {
is AccountStatus.CryptoPortfolio -> accountStatus.account.isMainAccount
get() = accountStatuses
.filterCryptoPortfolio()
.first { accountStatus ->
when (accountStatus) {
is AccountStatus.CryptoPortfolio -> accountStatus.account.isMainAccount
}
}
} as AccountStatus.CryptoPortfolio
fun flattenCurrencies(): List<CryptoCurrencyStatus> = accountStatuses
.filterCryptoPortfolio()
.map { accountStatus -> accountStatus.flattenCurrencies() }
.flatten()

View file

@ -5,10 +5,10 @@ import com.tangem.domain.models.account.Account
import com.tangem.domain.models.account.AccountId
/**
* Produces a flow of [Account.CryptoPortfolio] for a single account identified by [Params.accountId].
* Produces a flow of [Account] for a single account identified by [Params.accountId].
* The flow emits updates whenever the account's portfolio changes.
*/
interface SingleAccountProducer : FlowProducer<Account.CryptoPortfolio> {
interface SingleAccountProducer : FlowProducer<Account> {
data class Params(val accountId: AccountId)

View file

@ -28,7 +28,7 @@ interface AccountsCRUDRepository {
* Retrieves a specific account by its unique identifier
*
* @param accountId the unique identifier of the account
* @return an [Option] containing the [Account.CryptoPortfolio] if found, or `Option.None` if not
* @return an [Option] containing the [Account] if found, or `Option.None` if not
*/
suspend fun getAccountSync(accountId: AccountId): Option<Account.CryptoPortfolio>

View file

@ -3,9 +3,12 @@ package com.tangem.domain.account.supplier
import com.tangem.domain.account.producer.SingleAccountProducer
import com.tangem.domain.core.flow.FlowCachingSupplier
import com.tangem.domain.models.account.Account
import com.tangem.domain.models.account.AccountId
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.filterIsInstance
/**
* Supplies instances of [SingleAccountProducer] that produce flows of [Account.CryptoPortfolio]
* Supplies instances of [SingleAccountProducer] that produce flows of [Account]
* for individual accounts. Each producer is uniquely identified by its [SingleAccountProducer.Params].
*
* @property factory A factory to create instances of [SingleAccountProducer].
@ -14,4 +17,9 @@ import com.tangem.domain.models.account.Account
abstract class SingleAccountSupplier(
override val factory: SingleAccountProducer.Factory,
override val keyCreator: (SingleAccountProducer.Params) -> String,
) : FlowCachingSupplier<SingleAccountProducer, SingleAccountProducer.Params, Account.CryptoPortfolio>()
) : FlowCachingSupplier<SingleAccountProducer, SingleAccountProducer.Params, Account>() {
fun filterPaymentAccount(accountId: AccountId): Flow<Account.Payment> {
return invoke(params = SingleAccountProducer.Params(accountId)).filterIsInstance()
}
}

View file

@ -294,6 +294,7 @@ internal class DefaultSingleAccountStatusListProducer @AssistedInject constructo
return map { accountStatus ->
when (accountStatus) {
is AccountStatus.CryptoPortfolio -> accountStatus.tokenList.totalFiatBalance
is AccountStatus.Payment -> accountStatus.totalFiatBalance
}
}
}

View file

@ -9,7 +9,7 @@ import com.tangem.domain.account.repository.AccountsCRUDRepository
import com.tangem.domain.account.status.producer.SingleAccountStatusListProducer
import com.tangem.domain.account.status.supplier.SingleAccountStatusListSupplier
import com.tangem.domain.models.account.AccountId
import com.tangem.domain.models.account.AccountStatus
import com.tangem.domain.models.account.filterCryptoPortfolio
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.referral.ReferralRepository
@ -68,7 +68,7 @@ class ArchiveCryptoPortfolioUseCase(
val account = accountStatusList.accountStatuses
.asSequence()
.filterIsInstance<AccountStatus.CryptoPortfolio>()
.filterCryptoPortfolio()
.firstOrNull { it.accountId == accountId }
ensureNotNull(account) {

View file

@ -48,10 +48,12 @@ class ToggleTokenListGroupingUseCaseV2(
account.copy(tokenList = account.tokenList.reverseGroupType())
}
val updatedCryptoAccount =
updatedAccountList.firstOrNull { it is AccountStatus.CryptoPortfolio } as? AccountStatus.CryptoPortfolio
accountStatusList.copy(
accountStatuses = updatedAccountList,
groupType = when (updatedAccountList.firstOrNull()?.getCryptoTokenList()) {
groupType = when (updatedCryptoAccount?.tokenList) {
is TokenList.GroupedByNetwork -> TokensGroupType.NETWORK
is TokenList.Ungrouped -> TokensGroupType.NONE
else -> accountStatusList.groupType

View file

@ -7,6 +7,7 @@ import com.tangem.domain.account.status.model.AccountCryptoCurrencyStatuses
import com.tangem.domain.models.account.Account
import com.tangem.domain.models.account.AccountStatus
import com.tangem.domain.models.account.DerivationIndex
import com.tangem.domain.models.account.filterCryptoPortfolio
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.network.Network
import com.tangem.lib.crypto.derivation.AccountNodeRecognizer
@ -49,7 +50,7 @@ internal object AccountCryptoCurrencyStatusFinder {
): AccountCryptoCurrencyStatus? {
return accountStatusList.getExpectedAccountStatuses(network)
.asSequence()
.filterIsInstance<AccountStatus.CryptoPortfolio>()
.filterCryptoPortfolio()
.mapNotNull { accountStatus ->
val status = accountStatus.flattenCurrencies().firstOrNull { it.currency.id == currencyId }
?: return@mapNotNull null
@ -78,7 +79,7 @@ internal object AccountCryptoCurrencyStatusFinder {
return accountStatusList.getExpectedAccountStatuses(networks)
.asSequence()
.filterIsInstance<AccountStatus.CryptoPortfolio>()
.filterCryptoPortfolio()
.associate { accountStatus ->
val statuses = accountStatus.flattenCurrencies()
.filter { it.currency.id in currencyIds }
@ -108,7 +109,7 @@ internal object AccountCryptoCurrencyStatusFinder {
derivationPath = derivationPath,
)
.asSequence()
.filterIsInstance<AccountStatus.CryptoPortfolio>()
.filterCryptoPortfolio()
.mapNotNull { accountStatus ->
val status = accountStatus.flattenCurrencies().firstOrNull {
val currency = it.currency
@ -156,8 +157,8 @@ internal object AccountCryptoCurrencyStatusFinder {
DerivationIndex.Main.value -> listOf(mainAccount)
// currency only in the account with specific derivation index or in the main account
else -> {
val accountStatus = accountStatuses.firstOrNull {
val cryptoPortfolio = it.account as? Account.CryptoPortfolio ?: return@firstOrNull false
val accountStatus = accountStatuses.firstOrNull { accountStatus ->
val cryptoPortfolio = accountStatus.account as? Account.CryptoPortfolio ?: return@firstOrNull false
cryptoPortfolio.derivationIndex.value == possibleAccountIndex
}
@ -172,8 +173,8 @@ internal object AccountCryptoCurrencyStatusFinder {
if (possibleAccountIndexes.isEmpty()) return this@getExpectedAccountStatuses.accountStatuses
val accountStatuses = this@getExpectedAccountStatuses.accountStatuses.filter {
val cryptoPortfolio = it.account as? Account.CryptoPortfolio ?: return@filter false
val accountStatuses = this@getExpectedAccountStatuses.accountStatuses.filter { accountStatus ->
val cryptoPortfolio = accountStatus.account as? Account.CryptoPortfolio ?: return@filter false
cryptoPortfolio.derivationIndex.value in possibleAccountIndexes
}

View file

@ -109,7 +109,7 @@ sealed interface Account {
raise(AccountNameError(cause = it))
}
val derivationIndex = DerivationIndex(value = derivationIndex).getOrElse {
val index = DerivationIndex(value = derivationIndex).getOrElse {
raise(DerivationIndexError(cause = it))
}
@ -117,7 +117,7 @@ sealed interface Account {
accountId = accountId,
accountName = accountName,
icon = icon,
derivationIndex = derivationIndex,
derivationIndex = index,
cryptoCurrencies = cryptoCurrencies,
)
}
@ -175,11 +175,12 @@ sealed interface Account {
}
}
class Payment : Account {
override val accountId: AccountId
get() = TODO("Not yet implemented")
override val accountName: AccountName
get() = TODO("Not yet implemented")
@Serializable
data class Payment(
override val accountId: AccountId,
override val accountName: AccountName,
val cryptoCurrencies: List<CryptoCurrency>,
) : Account {
init {
error("Not yet implemented")
@ -190,5 +191,5 @@ sealed interface Account {
val Account.derivationIndex: DerivationIndex?
get() = when (this) {
is Account.CryptoPortfolio -> derivationIndex
is Account.Payment -> TODO("[REDACTED_JIRA]")
is Account.Payment -> null
}

View file

@ -71,5 +71,9 @@ data class AccountId private constructor(
return AccountId(value = value, userWalletId = userWalletId)
}
fun forPaymentAccount(userWalletId: UserWalletId): AccountId {
return AccountId(value = "payment_$userWalletId", userWalletId = userWalletId)
}
}
}

View file

@ -1,6 +1,7 @@
package com.tangem.domain.models.account
import com.tangem.domain.core.lce.Lce
import com.tangem.domain.models.TotalFiatBalance
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.quote.PriceChange
import com.tangem.domain.models.tokenlist.TokenList
@ -33,13 +34,23 @@ sealed interface AccountStatus {
override val account: Account.CryptoPortfolio,
val tokenList: TokenList,
val priceChangeLce: Lce<Unit, PriceChange>,
) : AccountStatus {
fun flattenCurrencies(): List<CryptoCurrencyStatus> {
return tokenList.flattenCurrencies()
}
}
@Serializable
data class Payment(
override val account: Account.Payment,
val totalFiatBalance: TotalFiatBalance,
) : AccountStatus
}
fun flattenCurrencies(): List<CryptoCurrencyStatus> = when (this) {
is CryptoPortfolio -> tokenList.flattenCurrencies()
}
fun Iterable<AccountStatus>.filterCryptoPortfolio(): List<AccountStatus.CryptoPortfolio> {
return filterIsInstance<AccountStatus.CryptoPortfolio>()
}
fun getCryptoTokenList(): TokenList = when (this) {
is CryptoPortfolio -> tokenList
}
fun Sequence<AccountStatus>.filterCryptoPortfolio(): Sequence<AccountStatus.CryptoPortfolio> {
return filterIsInstance<AccountStatus.CryptoPortfolio>()
}

View file

@ -14,8 +14,8 @@ data class SwapTransactionListModel(
val toCryptoCurrencyId: String,
val fromCryptoCurrency: CryptoCurrency,
val toCryptoCurrency: CryptoCurrency,
val fromAccount: Account.CryptoPortfolio?,
val toAccount: Account.CryptoPortfolio?,
val fromAccount: Account?,
val toAccount: Account?,
val transactions: List<SwapTransactionModel>,
)

View file

@ -30,8 +30,8 @@ interface SwapTransactionRepository {
userWalletId: UserWalletId,
fromCryptoCurrency: CryptoCurrency,
toCryptoCurrency: CryptoCurrency,
fromAccount: Account.CryptoPortfolio?,
toAccount: Account.CryptoPortfolio?,
fromAccount: Account?,
toAccount: Account?,
transaction: SwapTransactionModel,
)

View file

@ -22,8 +22,8 @@ class SwapTransactionSentUseCase(
userWallet: UserWallet,
fromCryptoCurrencyStatus: CryptoCurrencyStatus,
toCryptoCurrencyStatus: CryptoCurrencyStatus,
fromAccount: Account.CryptoPortfolio?,
toAccount: Account.CryptoPortfolio?,
fromAccount: Account?,
toAccount: Account?,
swapDataTransactionModel: SwapDataTransactionModel,
provider: ExpressProvider,
txHash: String,

View file

@ -8,7 +8,7 @@ import com.tangem.domain.models.wallet.UserWallet
data class WcSession(
val wallet: UserWallet,
val account: Account?,
val account: Account.CryptoPortfolio?,
val networks: Set<Network>,
val sdkModel: WcSdkSession,
val securityStatus: CheckDAppResult,

View file

@ -60,5 +60,7 @@ interface PortfolioSelectorController {
suspend fun isAccountModeSync(): Boolean
fun selectAccount(accountId: AccountId?)
fun selectedAccountWithData(portfolioFetcher: PortfolioFetcher): Flow<Pair<UserWallet, AccountStatus>?>
fun selectedAccountWithData(
portfolioFetcher: PortfolioFetcher,
): Flow<Pair<UserWallet, AccountStatus.CryptoPortfolio>?>
}

View file

@ -3,6 +3,7 @@ package com.tangem.features.account.selector
import com.tangem.domain.account.usecase.IsAccountsModeEnabledUseCase
import com.tangem.domain.models.account.AccountId
import com.tangem.domain.models.account.AccountStatus
import com.tangem.domain.models.account.filterCryptoPortfolio
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.features.account.PortfolioFetcher
import com.tangem.features.account.PortfolioSelectorController
@ -35,21 +36,23 @@ internal class DefaultPortfolioSelectorController @Inject constructor(
_selectedAccount.tryEmit(accountId)
}
override fun selectedAccountWithData(portfolioFetcher: PortfolioFetcher): Flow<Pair<UserWallet, AccountStatus>?> =
combine(
flow = _selectedAccount,
flow2 = portfolioFetcher.data,
transform = { accountId, data ->
accountId ?: return@combine null
var result: Pair<UserWallet, AccountStatus>? = null
override fun selectedAccountWithData(
portfolioFetcher: PortfolioFetcher,
): Flow<Pair<UserWallet, AccountStatus.CryptoPortfolio>?> = combine(
flow = _selectedAccount,
flow2 = portfolioFetcher.data,
transform = { accountId, data ->
accountId ?: return@combine null
var result: Pair<UserWallet, AccountStatus.CryptoPortfolio>? = null
data.balances.forEach { wallet, balance ->
val accountStatuses = balance.accountsBalance.accountStatuses
.find { accountId == it.account.accountId }
if (accountStatuses != null) result = balance.userWallet to accountStatuses
}
data.balances.forEach { wallet, balance ->
val accountStatuses = balance.accountsBalance.accountStatuses
.filterCryptoPortfolio()
.find { accountId == it.account.accountId }
if (accountStatuses != null) result = balance.userWallet to accountStatuses
}
return@combine result
},
)
return@combine result
},
)
}

View file

@ -184,6 +184,7 @@ internal class PortfolioSelectorModel @Inject constructor(
val account = accountStatus.account
val accountBalance = when (accountStatus) {
is AccountStatus.CryptoPortfolio -> accountStatus.tokenList.totalFiatBalance
is AccountStatus.Payment -> accountStatus.totalFiatBalance
}
val accountItemUM = AccountPortfolioItemUMConverter(
onClick = { selectorController.selectAccount(account.accountId) },

View file

@ -325,6 +325,7 @@ internal class AddToPortfolioModel @Inject constructor(
): CryptoCurrency? {
val accountIndex = when (val accountStatus = account.account) {
is AccountStatus.CryptoPortfolio -> accountStatus.account.derivationIndex
is AccountStatus.Payment -> TODO("[REDACTED_JIRA]")
}
return getTokenMarketCryptoCurrency(
userWalletId = userWallet.walletId,

View file

@ -174,6 +174,7 @@ internal class AddToPortfolioPreselectedDataModel @Inject constructor(
val availableToAddAccounts = accounts.mapNotNull { accountStatus ->
val accountIndex = when (accountStatus) {
is AccountStatus.CryptoPortfolio -> accountStatus.account.derivationIndex
is AccountStatus.Payment -> TODO("[REDACTED_JIRA]")
}
val cryptoCurrency = getTokenMarketCryptoCurrency(
@ -220,6 +221,7 @@ internal class AddToPortfolioPreselectedDataModel @Inject constructor(
): CryptoCurrency? {
val accountIndex = when (val accountStatus = account.account) {
is AccountStatus.CryptoPortfolio -> accountStatus.account.derivationIndex
is AccountStatus.Payment -> TODO("[REDACTED_JIRA]")
}
return getTokenMarketCryptoCurrency(
userWalletId = userWallet.walletId,

View file

@ -13,7 +13,7 @@ import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.iconResId
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.domain.models.account.AccountStatus
import com.tangem.domain.models.account.AccountStatus.*
import com.tangem.features.feed.components.market.details.portfolio.add.SelectedNetwork
import com.tangem.features.feed.components.market.details.portfolio.add.SelectedPortfolio
import com.tangem.features.feed.components.market.details.portfolio.add.impl.AddTokenComponent
@ -36,7 +36,7 @@ internal class AddTokenUiBuilder @Inject constructor(
}
private fun createPortfolio(selectedPortfolio: SelectedPortfolio): PortfolioSelectUM {
val accountIcon: AccountIconUM.CryptoPortfolio?
val accountIcon: AccountIconUM?
val portfolioName: TextReference
when (selectedPortfolio.isAccountMode) {
false -> {
@ -47,7 +47,8 @@ internal class AddTokenUiBuilder @Inject constructor(
val accountStatus = selectedPortfolio.account.account
portfolioName = accountStatus.account.accountName.toUM().value
accountIcon = when (accountStatus) {
is AccountStatus.CryptoPortfolio -> CryptoPortfolioIconConverter.convert(accountStatus.account.icon)
is CryptoPortfolio -> CryptoPortfolioIconConverter.convert(accountStatus.account.icon)
is Payment -> AccountIconUM.Payment
}
}
}

View file

@ -202,6 +202,7 @@ internal class NewMarketsPortfolioDelegate @AssistedInject constructor(
val currencyId = status.currency.id.rawCurrencyId ?: return@filter false
getTokenIdIfL2Network(currencyId.value) == currencyRawId.value
}
is AccountStatus.Payment -> TODO("[REDACTED_JIRA]")
}
return accountStatuses.map { accountStatus ->
AccountWithAdded(

View file

@ -214,9 +214,10 @@ internal class CustomTokenSelectorModel @Inject constructor(
val accounts = singleAccountStatusListSupplier(mode.userWalletId)
.first().accountStatuses
val accountStatus = accounts.find {
when (it) {
is AccountStatus.CryptoPortfolio -> it.sameNodeAndNotMain()
val accountStatus = accounts.find { account ->
when (account) {
is AccountStatus.CryptoPortfolio -> account.sameNodeAndNotMain()
is AccountStatus.Payment -> TODO("[REDACTED_JIRA]")
}
}

View file

@ -12,6 +12,7 @@ import com.tangem.domain.managetokens.model.CurrencyUnsupportedState
import com.tangem.domain.managetokens.model.ManageTokensListConfig
import com.tangem.domain.managetokens.model.ManagedCryptoCurrency
import com.tangem.domain.managetokens.repository.CustomTokensRepository
import com.tangem.domain.models.account.Account
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.network.Network
import com.tangem.domain.models.wallet.UserWalletId
@ -88,7 +89,7 @@ internal class ManageTokensUseCasesFacade @AssistedInject constructor(
val account = singleAccountSupplier.getSyncOrNull(
params = SingleAccountProducer.Params(accountId = mode.accountId),
)
) as? Account.CryptoPortfolio
?: return IllegalStateException("Account not found").left()
(account.cryptoCurrencies + added - removed).any {

View file

@ -315,6 +315,7 @@ internal class AddToPortfolioModel @Inject constructor(
): CryptoCurrency? {
val accountIndex = when (account.account) {
is AccountStatus.CryptoPortfolio -> account.account.account.derivationIndex
is AccountStatus.Payment -> TODO("[REDACTED_JIRA]")
}
return getTokenMarketCryptoCurrency(
userWalletId = userWallet.walletId,

View file

@ -13,7 +13,7 @@ import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.iconResId
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.domain.models.account.AccountStatus
import com.tangem.domain.models.account.AccountStatus.*
import com.tangem.features.markets.impl.R
import com.tangem.features.markets.portfolio.add.api.SelectedNetwork
import com.tangem.features.markets.portfolio.add.api.SelectedPortfolio
@ -36,7 +36,7 @@ internal class AddTokenUiBuilder @Inject constructor(
}
private fun createPortfolio(selectedPortfolio: SelectedPortfolio): PortfolioSelectUM {
val accountIcon: AccountIconUM.CryptoPortfolio?
val accountIcon: AccountIconUM?
val portfolioName: TextReference
when (selectedPortfolio.isAccountMode) {
false -> {
@ -47,7 +47,8 @@ internal class AddTokenUiBuilder @Inject constructor(
val accountStatus = selectedPortfolio.account.account
portfolioName = accountStatus.account.accountName.toUM().value
accountIcon = when (accountStatus) {
is AccountStatus.CryptoPortfolio -> CryptoPortfolioIconConverter.convert(accountStatus.account.icon)
is CryptoPortfolio -> CryptoPortfolioIconConverter.convert(accountStatus.account.icon)
is Payment -> AccountIconUM.Payment
}
}
}

View file

@ -203,6 +203,7 @@ internal class NewMarketsPortfolioDelegate @AssistedInject constructor(
val currencyId = status.currency.id.rawCurrencyId ?: return@filter false
getTokenIdIfL2Network(currencyId.value) == currencyRawId.value
}
is AccountStatus.Payment -> TODO("[REDACTED_JIRA]")
}
return accountStatuses.map { accountStatus ->
AccountWithAdded(

View file

@ -45,6 +45,7 @@ internal class HotCryptoPortfolioDataLoader @Inject constructor(
val accountsWithHotCrypto = walletAccounts.accountStatuses.map { accountStatus ->
val account: AccountStatus.CryptoPortfolio = when (accountStatus) {
is AccountStatus.CryptoPortfolio -> accountStatus
is AccountStatus.Payment -> TODO("[REDACTED_JIRA]")
}
val addedHotCrypto = mapOfAddedCurrencies[account.account].orEmpty()
HotCryptoPortfolioData.Account(

View file

@ -37,7 +37,7 @@ internal class OnrampAddTokenUiBuilder @Inject constructor(
}
private suspend fun createPortfolio(tokenToAdd: AddHotCryptoData): PortfolioSelectUM {
val accountIcon: AccountIconUM.CryptoPortfolio?
val accountIcon: AccountIconUM?
val portfolioName: TextReference
val isAccountMode = isAccountsModeEnabledUseCase.invokeSync()
when (isAccountMode) {
@ -50,6 +50,7 @@ internal class OnrampAddTokenUiBuilder @Inject constructor(
portfolioName = accountStatus.account.accountName.toUM().value
accountIcon = when (accountStatus) {
is AccountStatus.CryptoPortfolio -> CryptoPortfolioIconConverter.convert(accountStatus.account.icon)
is AccountStatus.Payment -> AccountIconUM.Payment
}
}
}

View file

@ -23,7 +23,9 @@ internal class LoadingAccountTokenItemConverter(
).convert(TotalFiatBalance.Failed),
isExpanded = true,
isCollapsable = false,
tokens = currencies.flattenCurrencies().map(LoadingTokenListItemConverter::convert).toPersistentList(),
tokens = currencies.flattenCurrencies()
.map { LoadingTokenListItemConverter.convert(it.currency) }
.toPersistentList(),
)
}
}

View file

@ -3,6 +3,7 @@ package com.tangem.features.onramp.swap.availablepairs.entity.converters
import com.tangem.core.ui.components.currency.icon.CurrencyIconState
import com.tangem.core.ui.components.token.state.TokenItemState
import com.tangem.core.ui.components.tokenlist.state.TokensListItemUM
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.utils.converter.Converter
@ -11,12 +12,12 @@ import com.tangem.utils.converter.Converter
*
[REDACTED_AUTHOR]
*/
internal object LoadingTokenListItemConverter : Converter<CryptoCurrencyStatus, TokensListItemUM.Token> {
internal object LoadingTokenListItemConverter : Converter<CryptoCurrency, TokensListItemUM.Token> {
override fun convert(value: CryptoCurrencyStatus): TokensListItemUM.Token {
override fun convert(value: CryptoCurrency): TokensListItemUM.Token {
return TokensListItemUM.Token(
state = TokenItemState.Loading(
id = value.currency.id.value,
id = value.id.value,
iconState = CurrencyIconState.Loading,
titleState = TokenItemState.TitleState.Loading,
subtitleState = TokenItemState.SubtitleState.Loading,

View file

@ -18,7 +18,9 @@ internal class SetLoadingTokenItemsTransformer(
override fun transform(prevState: TokenListUM): TokenListUM {
return prevState.copy(
availableItems = LoadingTokenListItemConverter.convertList(input = statuses).toImmutableList(),
availableItems = LoadingTokenListItemConverter.convertList(
input = statuses.map(CryptoCurrencyStatus::currency),
).toImmutableList(),
unavailableItems = persistentListOf(),
warning = null,
)

View file

@ -21,6 +21,7 @@ import com.tangem.domain.core.utils.lceLoading
import com.tangem.domain.markets.GetMarketsTokenListFlowUseCase
import com.tangem.domain.models.account.Account
import com.tangem.domain.models.account.AccountStatus
import com.tangem.domain.models.account.filterCryptoPortfolio
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.tokenlist.TokenList
@ -287,7 +288,7 @@ internal class AvailableSwapPairsModel @Inject constructor(
): TokenListUMTransformer {
val (appCurrency, isBalanceHidden) = appCurrencyAndBalanceHiding
val filterByQueryAccountList = accountList
val filterByQueryAccountList: Map<Account.CryptoPortfolio, List<CryptoCurrencyStatus>> = accountList
.associate { accountStatus ->
when (accountStatus) {
is AccountStatus.CryptoPortfolio -> {
@ -300,6 +301,7 @@ internal class AvailableSwapPairsModel @Inject constructor(
accountStatus.account to statuses
}
is AccountStatus.Payment -> TODO("[REDACTED_JIRA]")
}
}
.filterValues { it.isNotEmpty() }
@ -360,7 +362,7 @@ internal class AvailableSwapPairsModel @Inject constructor(
onRefresh = {
modelScope.launch {
if (networkInfo != null) {
accountList.filterIsInstance<AccountStatus.CryptoPortfolio>()
accountList.filterCryptoPortfolio()
.forEach { (_, currencies) ->
updateAvailablePairs(networkInfo, currencies.flattenCurrencies())
}
@ -384,7 +386,7 @@ internal class AvailableSwapPairsModel @Inject constructor(
val accountList = accountListFlow.firstOrNull() ?: return@collectLatest
updateAvailablePairs(
networkInfo = networkInfo,
statuses = accountList.filterIsInstance<AccountStatus.CryptoPortfolio>()
statuses = accountList.filterCryptoPortfolio()
.flatMap { accountStatus ->
accountStatus.flattenCurrencies()
}.toSet().toList(),

View file

@ -2,6 +2,8 @@ package com.tangem.features.onramp.tokenlist.entity.transformer
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.models.account.AccountStatus
import com.tangem.domain.models.account.filterCryptoPortfolio
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.features.onramp.swap.availablepairs.entity.converters.LoadingAccountTokenItemConverter
import com.tangem.features.onramp.swap.availablepairs.entity.converters.LoadingTokenListItemConverter
import com.tangem.features.onramp.tokenlist.entity.TokenListUM
@ -22,6 +24,7 @@ internal class SetLoadingAccountTokenListTransformer(
val totalTokensCount = accountList.sumOf { account ->
when (account) {
is AccountStatus.CryptoPortfolio -> account.tokenList.flattenCurrencies().size
is AccountStatus.Payment -> TODO("[REDACTED_JIRA]")
}
}
@ -31,7 +34,7 @@ internal class SetLoadingAccountTokenListTransformer(
tokensListData = if (isAccountsMode) {
TokenListUMData.AccountList(
tokensList = accountListItemConverter.convertList(
accountList.filterIsInstance<AccountStatus.CryptoPortfolio>(),
accountList.filterCryptoPortfolio(),
).toPersistentList(),
totalTokensCount = totalTokensCount,
)
@ -40,8 +43,9 @@ internal class SetLoadingAccountTokenListTransformer(
tokensList = accountList.flatMap { account ->
when (account) {
is AccountStatus.CryptoPortfolio -> LoadingTokenListItemConverter.convertList(
account.tokenList.flattenCurrencies(),
account.tokenList.flattenCurrencies().map(CryptoCurrencyStatus::currency),
)
is AccountStatus.Payment -> TODO("[REDACTED_JIRA]")
}
}.toPersistentList(),
totalTokensCount = totalTokensCount,

View file

@ -295,13 +295,16 @@ internal class OnrampTokenListModel @Inject constructor(
)
}
private fun AccountStatusList.filterAccountsByQuery(query: String) = accountStatuses.asSequence()
private fun AccountStatusList.filterAccountsByQuery(
query: String,
): Map<Account.CryptoPortfolio, List<CryptoCurrencyStatus>> = accountStatuses.asSequence()
.associate { accountStatus ->
when (accountStatus) {
is AccountStatus.CryptoPortfolio -> {
val filteredList = accountStatus.tokenList.flattenCurrencies().filterByQuery(query = query)
accountStatus.account to filteredList
}
is AccountStatus.Payment -> TODO("[REDACTED_JIRA]")
}
}.filter { (_, value) -> value.isNotEmpty() }

View file

@ -6,6 +6,7 @@ import com.tangem.domain.account.producer.SingleAccountProducer
import com.tangem.domain.account.status.usecase.ManageCryptoCurrenciesUseCase
import com.tangem.domain.account.supplier.SingleAccountSupplier
import com.tangem.domain.models.PortfolioId
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.wallet.UserWalletId
@ -55,7 +56,10 @@ internal class ReferralInteractorImpl(
)
?: error("Account not found: ${portfolioId.accountId}")
account.derivationIndex
when (account) {
is Account.CryptoPortfolio -> account.derivationIndex
is Account.Payment -> TODO("[REDACTED_JIRA]")
}
}
is PortfolioId.Wallet -> null
}

View file

@ -127,6 +127,7 @@ internal class ReferralModel @Inject constructor(
val cryptoPortfolio = when (selectedAccount) {
is AccountStatus.CryptoPortfolio -> selectedAccount
is AccountStatus.Payment -> TODO("[REDACTED_JIRA]")
}
val awardCryptoCurrency = referralInteractor.getCryptoCurrency(

View file

@ -21,6 +21,7 @@ import com.tangem.core.decompose.model.getOrCreateModel
import com.tangem.core.decompose.navigation.inner.InnerRouter
import com.tangem.core.ui.decompose.ComposableContentComponent
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.domain.models.account.derivationIndex
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.features.send.v2.api.FeeSelectorBlockComponent
import com.tangem.features.send.v2.api.SendComponent

View file

@ -22,14 +22,17 @@ internal class SendAnalyticHelper @Inject constructor(
cryptoCurrency: CryptoCurrency,
sendUM: SendUM,
feeToken: CryptoCurrency,
account: Account.CryptoPortfolio?,
account: Account?,
) {
val destinationUM = sendUM.destinationUM as? DestinationUM.Content
val feeSelectorUM = sendUM.feeSelectorUM as? FeeSelectorUM.Content ?: return
val feeType = feeSelectorUM.toAnalyticType()
val feeTokenSymbol = feeToken.symbol
val isNotMainAccount = account != null && !account.isMainAccount
val derivationIndex = if (isNotMainAccount) account.derivationIndex.value else null
val derivationIndex = when (account) {
is Account.CryptoPortfolio -> if (!account.isMainAccount) account.derivationIndex else null
is Account.Payment -> null
null -> null
}
analyticsEventHandler.send(
SendAnalyticEvents.TransactionScreenOpened(
token = cryptoCurrency.symbol,
@ -37,7 +40,7 @@ internal class SendAnalyticHelper @Inject constructor(
blockchain = cryptoCurrency.network.name,
isNonceNotEmpty = feeSelectorUM.feeNonce is FeeNonce.Nonce,
ensStatus = getEnsStatus(sendUM),
derivationIndex = derivationIndex,
derivationIndex = derivationIndex?.value,
feeToken = feeTokenSymbol,
),
)

View file

@ -158,7 +158,7 @@ internal class SendConfirmComponent(
val feeCryptoCurrencyStatus: CryptoCurrencyStatus,
val cryptoCurrencyStatusFlow: StateFlow<CryptoCurrencyStatus>,
val feeCryptoCurrencyStatusFlow: StateFlow<CryptoCurrencyStatus>,
val accountFlow: StateFlow<Account.CryptoPortfolio?>,
val accountFlow: StateFlow<Account?>,
val isAccountModeFlow: StateFlow<Boolean>,
val appCurrency: AppCurrency,
val callback: ModelCallback,

View file

@ -147,7 +147,7 @@ internal class SendModel @Inject constructor(
),
)
val accountFlow: StateFlow<Account.CryptoPortfolio?>
val accountFlow: StateFlow<Account?>
field = MutableStateFlow(null)
val isAccountModeFlow: StateFlow<Boolean>
field = MutableStateFlow(false)

View file

@ -24,7 +24,7 @@ internal sealed class SendAmountComponentParams {
abstract val cryptoCurrency: CryptoCurrency
abstract val cryptoCurrencyStatusFlow: StateFlow<CryptoCurrencyStatus>
abstract val isBalanceHidingFlow: StateFlow<Boolean>
abstract val accountFlow: StateFlow<Account.CryptoPortfolio?>
abstract val accountFlow: StateFlow<Account?>
abstract val isAccountModeFlow: StateFlow<Boolean>
data class AmountParams(
@ -37,7 +37,7 @@ internal sealed class SendAmountComponentParams {
override val cryptoCurrencyStatusFlow: StateFlow<CryptoCurrencyStatus>,
override val isBalanceHidingFlow: StateFlow<Boolean>,
override val analyticsSendSource: CommonSendAnalyticEvents.CommonSendSource,
override val accountFlow: StateFlow<Account.CryptoPortfolio?>,
override val accountFlow: StateFlow<Account?>,
override val isAccountModeFlow: StateFlow<Boolean>,
val callback: ModelCallback,
val currentRoute: StateFlow<CommonSendRoute>,
@ -53,7 +53,7 @@ internal sealed class SendAmountComponentParams {
override val cryptoCurrencyStatusFlow: StateFlow<CryptoCurrencyStatus>,
override val isBalanceHidingFlow: StateFlow<Boolean>,
override val analyticsSendSource: CommonSendAnalyticEvents.CommonSendSource,
override val accountFlow: StateFlow<Account.CryptoPortfolio?>,
override val accountFlow: StateFlow<Account?>,
override val isAccountModeFlow: StateFlow<Boolean>,
val userWallet: UserWallet,
val blockClickEnableFlow: StateFlow<Boolean>,

View file

@ -149,7 +149,7 @@ internal class SendAmountModel @Inject constructor(
private suspend fun initMinBoundary(
cryptoCurrencyStatus: CryptoCurrencyStatus,
account: Account.CryptoPortfolio?,
account: Account?,
isAccountsMode: Boolean,
) {
minAmountBoundary = getMinimumTransactionAmountSyncUseCase(
@ -178,11 +178,7 @@ internal class SendAmountModel @Inject constructor(
}
}
private fun initialState(
cryptoCurrencyStatus: CryptoCurrencyStatus,
account: Account.CryptoPortfolio?,
isAccountsMode: Boolean,
) {
private fun initialState(cryptoCurrencyStatus: CryptoCurrencyStatus, account: Account?, isAccountsMode: Boolean) {
val userWallet = userWallet
if (uiState.value is AmountState.Empty && userWallet != null) {
val isOnlyOneWallet = getWalletsUseCase.invokeSync().size == 1

View file

@ -14,7 +14,7 @@ import com.tangem.core.ui.extensions.resourceReference
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
import com.tangem.domain.account.status.supplier.MultiAccountStatusListSupplier
import com.tangem.domain.account.usecase.IsAccountsModeEnabledUseCase
import com.tangem.domain.models.account.Account
import com.tangem.domain.models.account.filterCryptoPortfolio
import com.tangem.domain.models.network.CryptoCurrencyAddress
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.isLocked
@ -272,36 +272,40 @@ internal class SendDestinationModel @Inject constructor(
return combine(
flow = getWalletsUseCase().conflate(),
flow2 = multiAccountStatusListSupplier().conflate(),
) { wallets, accountList ->
) { wallets, accountStatusLists ->
val cryptoCurrencyNetwork = cryptoCurrency.network
coroutineScope {
accountList.mapNotNull { accountStatusList ->
val wallet =
wallets.filterNot { it.isLocked }.firstOrNull { it.walletId == accountStatusList.userWalletId }
?: return@mapNotNull null
accountStatusLists.mapNotNull { accountStatusList ->
val wallet = wallets
.filterNot { it.isLocked }
.firstOrNull { it.walletId == accountStatusList.userWalletId }
?: return@mapNotNull null
async {
accountStatusList.accountStatuses.map { accountStatus ->
async {
accountStatus.flattenCurrencies()
.filter { it.currency.network.rawId == cryptoCurrencyNetwork.rawId }
.mapNotNull { cryptoCurrencyStatus ->
val address = cryptoCurrencyStatus.value.networkAddress?.defaultAddress?.value
?: return@mapNotNull null
accountStatusList.flattenCurrencies()
.filter { it.currency.network.rawId == cryptoCurrencyNetwork.rawId }
.mapNotNull { cryptoCurrencyStatus ->
val address = cryptoCurrencyStatus.value.networkAddress?.defaultAddress?.value
?: return@mapNotNull null
async {
DestinationWalletUM(
name = wallet.name,
address = address,
cryptoCurrency = cryptoCurrencyStatus.currency,
userWalletId = wallet.walletId,
account = accountStatus.account as? Account.CryptoPortfolio,
)
}
}.awaitAll()
// Find the corresponding account from accountStatuses
val account = accountStatusList.accountStatuses
.filterCryptoPortfolio()
.firstOrNull { accountStatus ->
accountStatus.tokenList
.flattenCurrencies()
.any { it.currency.id == cryptoCurrencyStatus.currency.id }
}?.account
DestinationWalletUM(
name = wallet.name,
address = address,
cryptoCurrency = cryptoCurrencyStatus.currency,
userWalletId = wallet.walletId,
account = account,
)
}
}.awaitAll().flatten()
}
}.awaitAll().flatten()
}

View file

@ -1,9 +1,11 @@
package com.tangem.features.send.v2.subcomponents.destination.model.converters
import com.tangem.common.ui.account.AccountIconUM
import com.tangem.common.ui.account.AccountTitleUM
import com.tangem.common.ui.account.CryptoPortfolioIconConverter
import com.tangem.common.ui.account.toUM
import com.tangem.core.ui.extensions.stringReference
import com.tangem.domain.models.account.Account
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationRecipientListUM
import com.tangem.features.send.v2.subcomponents.destination.model.transformers.WALLET_DEFAULT_COUNT
@ -59,7 +61,12 @@ internal class SendRecipientWalletListConverter(
accountTitleUM = if (account != null && isAccountsMode) {
AccountTitleUM.Account(
name = account.accountName.toUM().value,
icon = CryptoPortfolioIconConverter.convert(account.icon),
icon = when (account) {
is Account.CryptoPortfolio -> CryptoPortfolioIconConverter.convert(
account.icon,
)
is Account.Payment -> AccountIconUM.Payment
},
prefixText = stringReference(StringsSigns.DOT),
)
} else {

View file

@ -20,5 +20,5 @@ data class DestinationWalletUM(
val userWalletId: UserWalletId,
val address: String,
val cryptoCurrency: CryptoCurrency,
val account: Account.CryptoPortfolio? = null,
val account: Account? = null,
)

View file

@ -24,7 +24,7 @@ internal sealed class SwapAmountComponentParams {
abstract val primaryCryptoCurrencyStatusFlow: StateFlow<CryptoCurrencyStatus>
abstract val secondaryCryptoCurrency: CryptoCurrency?
abstract val filterProviderTypes: List<ExpressProviderType>
abstract val accountFlow: StateFlow<Account.CryptoPortfolio?>
abstract val accountFlow: StateFlow<Account?>
abstract val isAccountModeFlow: StateFlow<Boolean>
data class AmountParams(
@ -37,7 +37,7 @@ internal sealed class SwapAmountComponentParams {
override val secondaryCryptoCurrency: CryptoCurrency?,
override val filterProviderTypes: List<ExpressProviderType> = emptyList(),
override val analyticsSendSource: CommonSendAnalyticEvents.CommonSendSource,
override val accountFlow: StateFlow<Account.CryptoPortfolio?>,
override val accountFlow: StateFlow<Account?>,
override val isAccountModeFlow: StateFlow<Boolean>,
val title: TextReference,
val callback: SwapAmountComponent.ModelCallback,
@ -54,7 +54,7 @@ internal sealed class SwapAmountComponentParams {
override val secondaryCryptoCurrency: CryptoCurrency?,
override val filterProviderTypes: List<ExpressProviderType> = emptyList(),
override val analyticsSendSource: CommonSendAnalyticEvents.CommonSendSource,
override val accountFlow: StateFlow<Account.CryptoPortfolio?>,
override val accountFlow: StateFlow<Account?>,
override val isAccountModeFlow: StateFlow<Boolean>,
val blockClickEnableFlow: StateFlow<Boolean>,
) : SwapAmountComponentParams()

View file

@ -30,7 +30,7 @@ internal class SwapAmountFieldConverter(
private val clickIntents: AmountScreenClickIntents,
private val isSingleWallet: Boolean,
private val isAccountsMode: Boolean,
private val account: Account.CryptoPortfolio?,
private val account: Account?,
) {
private val iconStateConverter = CryptoCurrencyToIconStateConverter()

View file

@ -21,7 +21,7 @@ internal class SwapAmountBalanceHiddenTransformer(
private val swapDirection: SwapDirection,
private val clickIntents: AmountScreenClickIntents,
private val isAccountsMode: Boolean,
private val account: Account.CryptoPortfolio?,
private val account: Account?,
) : Transformer<SwapAmountUM> {
override fun transform(prevState: SwapAmountUM): SwapAmountUM {

View file

@ -27,7 +27,7 @@ internal class SwapAmountPrimaryReadyStateTransformer(
private val isShowBestRateAnimation: Boolean,
private val isSingleWallet: Boolean,
private val isAccountsMode: Boolean,
private val account: Account.CryptoPortfolio?,
private val account: Account?,
) : Transformer<SwapAmountUM> {
private val amountFieldConverter = SwapAmountFieldConverter(

View file

@ -28,7 +28,7 @@ internal class SwapAmountSecondaryReadyStateTransformer(
private val isShowBestRateAnimation: Boolean,
private val isSingleWallet: Boolean,
private val isAccountsMode: Boolean,
private val account: Account.CryptoPortfolio?,
private val account: Account?,
) : Transformer<SwapAmountUM> {
private val amountFieldConverter = SwapAmountFieldConverter(

View file

@ -18,7 +18,7 @@ internal data class ConfirmData(
val feeError: GetFeeError?,
val fromCryptoCurrencyStatus: CryptoCurrencyStatus?,
val toCryptoCurrencyStatus: CryptoCurrencyStatus?,
val fromAccount: Account.CryptoPortfolio?,
val fromAccount: Account?,
val quote: SwapQuoteUM?,
val rateType: ExpressRateType?,
)

View file

@ -20,6 +20,7 @@ import com.tangem.core.decompose.navigation.inner.InnerRouter
import com.tangem.core.navigation.url.UrlOpener
import com.tangem.core.ui.decompose.ComposableContentComponent
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.domain.models.account.Account
import com.tangem.domain.swap.models.R
import com.tangem.domain.swap.models.SwapDirection
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents
@ -110,8 +111,11 @@ internal class DefaultSendWithSwapComponent @AssistedInject constructor(
}
is SendWithSwapConfirmComponent -> {
val fromCurrency = params.currency
val fromDerivationIndex = model.accountFlow.value?.derivationIndex?.value
.takeIf { model.isAccountModeFlow.value }
val fromDerivationIndex = when (val account = model.accountFlow.value) {
is Account.CryptoPortfolio -> account.derivationIndex.value
is Account.Payment -> TODO("[REDACTED_JIRA]")
null -> null
}.takeIf { model.isAccountModeFlow.value }
analyticsEventHandler.send(
CommonSendAnalyticEvents.ConfirmationScreenOpened(
categoryName = model.analyticCategoryName,

View file

@ -181,7 +181,7 @@ internal class SendWithSwapConfirmComponent @AssistedInject constructor(
val isBalanceHidingFlow: StateFlow<Boolean>,
val primaryCryptoCurrencyStatusFlow: StateFlow<CryptoCurrencyStatus>,
val primaryFeePaidCurrencyStatusFlow: StateFlow<CryptoCurrencyStatus>, // doesn't change if select gasless fee
val accountFlow: StateFlow<Account.CryptoPortfolio?>,
val accountFlow: StateFlow<Account?>,
val isAccountModeFlow: StateFlow<Boolean>,
val callback: ModelCallback,
)

View file

@ -24,6 +24,7 @@ import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.wrappedList
import com.tangem.domain.express.models.ExpressOperationType
import com.tangem.domain.express.models.ExpressProviderType
import com.tangem.domain.models.account.derivationIndex
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.wallet.isHotWallet

View file

@ -129,7 +129,7 @@ internal class SwapTransactionSender @AssistedInject constructor(
fromAmount: BigDecimal,
fromStatus: CryptoCurrencyStatus,
toStatus: CryptoCurrencyStatus,
fromAccount: Account.CryptoPortfolio?,
fromAccount: Account?,
fee: Fee,
feeExtended: TransactionFeeExtended?,
provider: ExpressProvider,

View file

@ -96,7 +96,7 @@ internal class SendWithSwapModel @Inject constructor(
),
)
val accountFlow: StateFlow<Account.CryptoPortfolio?>
val accountFlow: StateFlow<Account?>
field = MutableStateFlow(null)
val isAccountModeFlow: StateFlow<Boolean>

View file

@ -18,7 +18,7 @@ interface SwapComponent : ComposableContentComponent {
val screenSource: String,
val tangemPayInput: TangemPayInput? = null,
val preselectedToToken: CryptoCurrencyStatus? = null,
val preselectedAccount: Account.CryptoPortfolio? = null,
val preselectedAccount: Account? = null,
) {
data class TangemPayInput(
val cryptoAmount: BigDecimal,

View file

@ -47,8 +47,8 @@ internal class DefaultSwapTransactionRepository(
userWalletId: UserWalletId,
fromCryptoCurrency: CryptoCurrency,
toCryptoCurrency: CryptoCurrency,
fromAccount: Account.CryptoPortfolio?,
toAccount: Account.CryptoPortfolio?,
fromAccount: Account?,
toAccount: Account?,
transaction: SavedSwapTransactionModel,
) {
transaction.status?.let { status ->
@ -248,8 +248,8 @@ internal class DefaultSwapTransactionRepository(
userWalletId: UserWalletId,
fromCryptoCurrency: CryptoCurrency,
toCryptoCurrency: CryptoCurrency,
fromAccount: Account.CryptoPortfolio?,
toAccount: Account.CryptoPortfolio?,
fromAccount: Account?,
toAccount: Account?,
transactions: List<SavedSwapTransactionModel>,
): List<SavedSwapTransactionListModelInner> {
return addOrReplace(

View file

@ -120,8 +120,8 @@ internal class SavedSwapTransactionListConverter(
userWalletId: UserWalletId,
fromCryptoCurrency: CryptoCurrency,
toCryptoCurrency: CryptoCurrency,
fromAccount: Account.CryptoPortfolio?,
toAccount: Account.CryptoPortfolio?,
fromAccount: Account?,
toAccount: Account?,
tokenTransactions: List<SavedSwapTransactionModel>,
) = SavedSwapTransactionListModelInner(
userWalletId = userWalletId.stringValue,
@ -161,10 +161,7 @@ internal class SavedSwapTransactionListConverter(
}
}
private fun findAccountByDerivationIndex(
accountList: AccountList?,
derivationIndex: DerivationIndex?,
): Account.CryptoPortfolio? {
private fun findAccountByDerivationIndex(accountList: AccountList?, derivationIndex: DerivationIndex?): Account? {
return accountList?.accounts?.asSequence()?.filterIsInstance<Account.CryptoPortfolio>()
?.firstOrNull { it.derivationIndex == derivationIndex }
}

View file

@ -80,8 +80,8 @@ interface SwapInteractor {
swapData: SwapDataModel?,
currencyToSend: CryptoCurrencyStatus,
currencyToGet: CryptoCurrencyStatus,
fromAccount: Account.CryptoPortfolio?,
toAccount: Account.CryptoPortfolio?,
fromAccount: Account?,
toAccount: Account?,
amountToSwap: String,
includeFeeInAmount: IncludeFeeInAmount,
fee: TxFee?,
@ -129,8 +129,8 @@ interface SwapInteractor {
suspend fun storeSwapTransaction(
currencyToSend: CryptoCurrencyStatus,
currencyToGet: CryptoCurrencyStatus,
fromAccount: Account.CryptoPortfolio?,
toAccount: Account.CryptoPortfolio?,
fromAccount: Account?,
toAccount: Account?,
amount: SwapAmount,
swapProvider: SwapProvider,
swapDataModel: SwapDataModel,
@ -154,9 +154,9 @@ interface SwapInteractor {
@Suppress("LongParameterList")
suspend fun loadFeeForSwapTransaction(
fromToken: CryptoCurrencyStatus,
fromAccount: Account.CryptoPortfolio?,
fromAccount: Account?,
toToken: CryptoCurrencyStatus,
toAccount: Account.CryptoPortfolio?,
toAccount: Account?,
amount: String,
reduceBalanceBy: BigDecimal,
provider: SwapProvider,
@ -176,9 +176,9 @@ interface SwapInteractor {
@Suppress("LongParameterList")
suspend fun loadFeeForSwapTransaction(
fromToken: CryptoCurrencyStatus,
fromAccount: Account.CryptoPortfolio?,
fromAccount: Account?,
toToken: CryptoCurrencyStatus,
toAccount: Account.CryptoPortfolio?,
toAccount: Account?,
amount: String,
reduceBalanceBy: BigDecimal,
provider: SwapProvider,

View file

@ -29,6 +29,7 @@ import com.tangem.domain.demo.IsDemoCardUseCase
import com.tangem.domain.exchange.RampStateManager
import com.tangem.domain.express.models.ExpressOperationType
import com.tangem.domain.models.account.Account
import com.tangem.domain.models.account.AccountStatus
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.network.Network
@ -180,17 +181,11 @@ internal class SwapInteractorImpl @AssistedInject constructor(
SingleAccountStatusListProducer.Params(userWalletId),
)?.accountStatuses.orEmpty()
val walletAccountCurrencyStatusesExceptInitial = walletAccountCurrencyStatuses
.mapNotNull { accountStatus ->
val filteredCurrencies = accountStatus.flattenCurrencies().filter { status ->
val isDifferentCurrency = status.currency.network.backendId != currency.network.backendId ||
status.currency.getContractAddress() != currency.getContractAddress()
val hasValidStatus =
status.value is CryptoCurrencyStatus.Loaded || status.value is CryptoCurrencyStatus.NoAccount
val isNotCustomToken = !status.currency.isCustom
hasValidStatus && isDifferentCurrency && isNotCustomToken
val walletAccountCurrencyStatusesExceptInitial: Map<Account, List<CryptoCurrencyStatus>> =
walletAccountCurrencyStatuses.mapNotNull { accountStatus ->
val filteredCurrencies = when (accountStatus) {
is AccountStatus.CryptoPortfolio -> accountStatus.flattenCurrencies().filterCurrencies(currency)
is AccountStatus.Payment -> TODO("[REDACTED_JIRA]")
}
if (filteredCurrencies.isNotEmpty()) {
@ -234,6 +229,17 @@ internal class SwapInteractorImpl @AssistedInject constructor(
)
}
private fun List<CryptoCurrencyStatus>.filterCurrencies(currency: CryptoCurrency) = this.filter { status ->
val isDifferentCurrency = status.currency.network.backendId != currency.network.backendId ||
status.currency.getContractAddress() != currency.getContractAddress()
val hasValidStatus =
status.value is CryptoCurrencyStatus.Loaded || status.value is CryptoCurrencyStatus.NoAccount
val isNotCustomToken = !status.currency.isCustom
hasValidStatus && isDifferentCurrency && isNotCustomToken
}
private suspend fun getToCurrenciesGroup(
currency: CryptoCurrency,
leastPairs: List<SwapPairLeast>,
@ -293,7 +299,7 @@ internal class SwapInteractorImpl @AssistedInject constructor(
val isUnavailable = providers.isNullOrEmpty()
AccountSwapCurrency(
isAvailable = !isUnavailable,
account = cryptoPortfolio,
account = accountEntry,
cryptoCurrencyStatus = currencyStatus,
providers = providers.orEmpty(),
)
@ -400,7 +406,9 @@ internal class SwapInteractorImpl @AssistedInject constructor(
"""
Find the best quote
|- fromToken: $fromToken
|- fromAccount: $fromAccount
|- toToken: $toToken
|- toAccount: $toAccount
|- providers: $providers
|- amountToSwap: $amountToSwap
|- selectedFee: $txFeeSealedState
@ -767,8 +775,8 @@ internal class SwapInteractorImpl @AssistedInject constructor(
swapData: SwapDataModel?,
currencyToSend: CryptoCurrencyStatus,
currencyToGet: CryptoCurrencyStatus,
fromAccount: Account.CryptoPortfolio?,
toAccount: Account.CryptoPortfolio?,
fromAccount: Account?,
toAccount: Account?,
amountToSwap: String,
includeFeeInAmount: IncludeFeeInAmount,
fee: TxFee?,
@ -848,8 +856,8 @@ internal class SwapInteractorImpl @AssistedInject constructor(
swapData: SwapDataModel,
currencyToSendStatus: CryptoCurrencyStatus,
currencyToGetStatus: CryptoCurrencyStatus,
fromAccount: Account.CryptoPortfolio?,
toAccount: Account.CryptoPortfolio?,
fromAccount: Account?,
toAccount: Account?,
amountToSwap: String,
txFee: TxFee,
): SwapTransactionState {
@ -890,8 +898,8 @@ internal class SwapInteractorImpl @AssistedInject constructor(
swapData: SwapDataModel,
currencyToSendStatus: CryptoCurrencyStatus,
currencyToGetStatus: CryptoCurrencyStatus,
fromAccount: Account.CryptoPortfolio?,
toAccount: Account.CryptoPortfolio?,
fromAccount: Account?,
toAccount: Account?,
amountToSwap: String,
): SwapTransactionState {
val dexTransaction = swapData.transaction as? ExpressTransactionModel.DEX
@ -919,8 +927,8 @@ internal class SwapInteractorImpl @AssistedInject constructor(
swapData: SwapDataModel,
currencyToSendStatus: CryptoCurrencyStatus,
currencyToGetStatus: CryptoCurrencyStatus,
fromAccount: Account.CryptoPortfolio?,
toAccount: Account.CryptoPortfolio?,
fromAccount: Account?,
toAccount: Account?,
amount: SwapAmount,
txData: TransactionData,
payInAddress: String,
@ -988,8 +996,8 @@ internal class SwapInteractorImpl @AssistedInject constructor(
private suspend fun onSwapCex(
currencyToSend: CryptoCurrencyStatus,
currencyToGet: CryptoCurrencyStatus,
fromAccount: Account.CryptoPortfolio?,
toAccount: Account.CryptoPortfolio?,
fromAccount: Account?,
toAccount: Account?,
amount: SwapAmount,
txFee: TxFee?,
swapProvider: SwapProvider,
@ -1150,8 +1158,8 @@ internal class SwapInteractorImpl @AssistedInject constructor(
override suspend fun storeSwapTransaction(
currencyToSend: CryptoCurrencyStatus,
currencyToGet: CryptoCurrencyStatus,
fromAccount: Account.CryptoPortfolio?,
toAccount: Account.CryptoPortfolio?,
fromAccount: Account?,
toAccount: Account?,
amount: SwapAmount,
swapProvider: SwapProvider,
swapDataModel: SwapDataModel,
@ -1187,9 +1195,9 @@ internal class SwapInteractorImpl @AssistedInject constructor(
@Suppress("LongParameterList")
override suspend fun loadFeeForSwapTransaction(
fromToken: CryptoCurrencyStatus,
fromAccount: Account.CryptoPortfolio?,
fromAccount: Account?,
toToken: CryptoCurrencyStatus,
toAccount: Account.CryptoPortfolio?,
toAccount: Account?,
amount: String,
reduceBalanceBy: BigDecimal,
provider: SwapProvider,
@ -1225,9 +1233,9 @@ internal class SwapInteractorImpl @AssistedInject constructor(
override suspend fun loadFeeForSwapTransaction(
fromToken: CryptoCurrencyStatus,
fromAccount: Account.CryptoPortfolio?,
fromAccount: Account?,
toToken: CryptoCurrencyStatus,
toAccount: Account.CryptoPortfolio?,
toAccount: Account?,
amount: String,
reduceBalanceBy: BigDecimal,
provider: SwapProvider,

View file

@ -17,8 +17,8 @@ interface SwapTransactionRepository {
userWalletId: UserWalletId,
fromCryptoCurrency: CryptoCurrency,
toCryptoCurrency: CryptoCurrency,
fromAccount: Account.CryptoPortfolio?,
toAccount: Account.CryptoPortfolio?,
fromAccount: Account?,
toAccount: Account?,
transaction: SavedSwapTransactionModel,
)

View file

@ -13,8 +13,8 @@ data class SavedSwapTransactionListModel(
val toCryptoCurrencyId: String,
val fromCryptoCurrency: CryptoCurrency,
val toCryptoCurrency: CryptoCurrency,
val fromAccount: Account.CryptoPortfolio?,
val toAccount: Account.CryptoPortfolio?,
val fromAccount: Account?,
val toAccount: Account?,
val transactions: List<SavedSwapTransactionModel>,
)

View file

@ -36,8 +36,8 @@ sealed class SwapTransactionState {
data class StoreTransactionData(
val currencyToSend: CryptoCurrencyStatus,
val currencyToGet: CryptoCurrencyStatus,
val fromAccount: Account.CryptoPortfolio?,
val toAccount: Account.CryptoPortfolio?,
val fromAccount: Account?,
val toAccount: Account?,
val amount: SwapAmount,
val swapProvider: SwapProvider,
val swapDataModel: SwapDataModel,

View file

@ -22,6 +22,7 @@ import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
import com.tangem.domain.models.account.Account
import com.tangem.domain.models.account.AccountId
import com.tangem.domain.models.account.AccountStatus
import com.tangem.domain.models.account.filterCryptoPortfolio
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.wallets.analytics.WalletSettingsAnalyticEvents
@ -84,11 +85,11 @@ internal class AccountItemsDelegate @Inject constructor(
return WalletSettingsAccountsUM.Account(state = accountItemUM)
}
fun mapAccount(account: AccountStatus): WalletSettingsAccountsUM = when (account) {
fun mapAccount(account: AccountStatus.CryptoPortfolio): WalletSettingsAccountsUM = when (account) {
is AccountStatus.CryptoPortfolio -> account.mapCryptoPortfolio()
}
val accounts = accountStatusList.accountStatuses
val accounts = accountStatusList.accountStatuses.filterCryptoPortfolio()
val header = WalletSettingsAccountsUM.Header(
id = "accounts_header",

View file

@ -2,7 +2,7 @@ package com.tangem.feature.wallet.presentation.organizetokens.utils
import com.tangem.domain.account.models.AccountStatusList
import com.tangem.domain.account.status.model.AccountCryptoCurrencies
import com.tangem.domain.models.account.Account
import com.tangem.domain.models.account.filterCryptoPortfolio
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.tokenlist.TokenList
import com.tangem.feature.wallet.presentation.organizetokens.model.DraggableItem
@ -34,6 +34,7 @@ internal class CryptoCurrenciesIdsResolver {
}
}
@Suppress("UseOrEmpty")
fun resolveV2(tokensListUM: OrganizeTokensListUM, accountStatusList: AccountStatusList?): AccountCryptoCurrencies {
val draggableTokens = when (tokensListUM) {
OrganizeTokensListUM.EmptyList -> return emptyMap()
@ -43,10 +44,11 @@ internal class CryptoCurrenciesIdsResolver {
}
return accountStatusList?.accountStatuses
?.filter { it.getCryptoTokenList() != TokenList.Empty }
?.filterCryptoPortfolio()
?.filter { it.tokenList != TokenList.Empty }
?.associate { accountStatus ->
val currencies = accountStatus.flattenCurrencies()
accountStatus.account as Account.CryptoPortfolio to draggableTokens
accountStatus.account to draggableTokens
.asSequence()
.filter { it.accountId == accountStatus.account.accountId.value }
.mapNotNull { sortedToken ->

View file

@ -6,7 +6,7 @@ import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.models.TokensGroupType
import com.tangem.domain.models.TokensSortType
import com.tangem.domain.models.TotalFiatBalance
import com.tangem.domain.models.account.AccountStatus
import com.tangem.domain.models.account.filterCryptoPortfolio
import com.tangem.domain.models.tokenlist.TokenList
import com.tangem.feature.wallet.presentation.organizetokens.model.DraggableItem
import com.tangem.feature.wallet.presentation.organizetokens.model.OrganizeTokensListUM
@ -61,7 +61,7 @@ internal class AccountTokenItemConverter(
isGrouped = isGrouping,
items = value.accountStatuses
.asSequence()
.filterIsInstance<AccountStatus.CryptoPortfolio>()
.filterCryptoPortfolio()
.flatMap { accountStatus ->
if (accountStatus.tokenList != TokenList.Empty) {
buildList {

View file

@ -2,7 +2,6 @@ package com.tangem.feature.wallet.presentation.organizetokens.utils.converter.it
import com.tangem.domain.account.status.model.AccountCryptoCurrencyStatus
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.models.account.Account
import com.tangem.domain.models.account.AccountStatus
import com.tangem.domain.models.tokenlist.TokenList
import com.tangem.feature.wallet.presentation.organizetokens.model.DraggableItem
@ -13,27 +12,26 @@ import kotlinx.collections.immutable.toPersistentList
internal class OrganizedTokenListConverter(
private val appCurrency: AppCurrency,
) : Converter<AccountStatus, PersistentList<DraggableItem>> {
) : Converter<AccountStatus.CryptoPortfolio, PersistentList<DraggableItem>> {
private val tokensConverter by lazy { CryptoCurrencyToDraggableItemConverterV2(appCurrency) }
private val groupsConverter by lazy {
NetworkGroupToDraggableItemsConverterV2(tokensConverter)
}
override fun convert(value: AccountStatus): PersistentList<DraggableItem> {
val cryptoAccount = value.account as? Account.CryptoPortfolio ?: return persistentListOf()
return when (val tokenList = value.getCryptoTokenList()) {
override fun convert(value: AccountStatus.CryptoPortfolio): PersistentList<DraggableItem> {
return when (val tokenList = value.tokenList) {
is TokenList.GroupedByNetwork -> groupsConverter.convertList(
tokenList.groups.map { cryptoAccount to it },
tokenList.groups.map { value.account to it },
)
.flatten()
.toPersistentList()
is TokenList.Ungrouped -> tokensConverter.convertList(
value.flattenCurrencies().map {
value.flattenCurrencies().map { cryptoCurrencyStatus ->
AccountCryptoCurrencyStatus(
account = cryptoAccount,
status = it,
account = value.account,
status = cryptoCurrencyStatus,
)
},
).toPersistentList()

View file

@ -241,10 +241,11 @@ internal class GetSingleWalletWarningsFactory @Inject constructor(
}
}
private fun getAccountStatusFlow(userWallet: UserWallet): Flow<AccountStatus> {
private fun getAccountStatusFlow(userWallet: UserWallet): Flow<AccountStatus.CryptoPortfolio> {
val accountId = AccountId.forMainCryptoPortfolio(userWalletId = userWallet.walletId)
return singleAccountStatusSupplier(SingleAccountStatusProducer.Params(accountId))
.filterIsInstance<AccountStatus.CryptoPortfolio>()
.distinctUntilChanged()
.conflate()
}

View file

@ -14,6 +14,7 @@ import com.tangem.domain.models.TotalFiatBalance
import com.tangem.domain.models.account.Account
import com.tangem.domain.models.account.AccountId
import com.tangem.domain.models.account.AccountStatus
import com.tangem.domain.models.account.filterCryptoPortfolio
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.tokenlist.TokenList
@ -144,6 +145,7 @@ internal class TokenListStateConverter(
}
val accountItems = accountList.accountStatuses
.filterCryptoPortfolio()
.map { accountStatus ->
when (accountStatus) {
is AccountStatus.CryptoPortfolio -> accountStatus.map()

View file

@ -4,6 +4,7 @@ import com.tangem.domain.account.models.AccountStatusList
import com.tangem.domain.account.status.producer.SingleAccountStatusListProducer
import com.tangem.domain.account.status.supplier.SingleAccountStatusListSupplier
import com.tangem.domain.models.account.AccountStatus
import com.tangem.domain.models.account.filterCryptoPortfolio
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.wallet.UserWallet
import kotlinx.coroutines.flow.Flow
@ -45,11 +46,9 @@ internal abstract class BasicWalletSubscriber : WalletSubscriber() {
protected fun getMainAccountStatusFlow(): Flow<AccountStatus.CryptoPortfolio> {
return getAccountStatusListFlow()
.mapNotNull { accountStatusList ->
accountStatusList.accountStatuses.find { accountStatus ->
when (accountStatus) {
is AccountStatus.CryptoPortfolio -> accountStatus.account.isMainAccount
}
} as? AccountStatus.CryptoPortfolio
accountStatusList.accountStatuses
.filterCryptoPortfolio()
.find { accountStatus -> accountStatus.account.isMainAccount }
}
.distinctUntilChanged()
.conflate()

View file

@ -27,7 +27,6 @@ import com.tangem.domain.account.supplier.SingleAccountListSupplier
import com.tangem.domain.account.usecase.IsAccountsModeEnabledUseCase
import com.tangem.domain.models.account.Account
import com.tangem.domain.models.account.AccountStatus
import com.tangem.domain.models.account.derivationIndex
import com.tangem.domain.models.network.Network
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.UserWalletId
@ -105,7 +104,7 @@ internal class WcPairModel @Inject constructor(
private val selectedUserWalletFlow: MutableStateFlow<UserWallet> by lazy {
MutableStateFlow(getWalletsUseCase.invokeSync().first { it.walletId == params.userWalletId })
}
private val selectedPortfolio = MutableSharedFlow<Pair<UserWallet, AccountStatus>>(
private val selectedPortfolio = MutableSharedFlow<Pair<UserWallet, AccountStatus.CryptoPortfolio>>(
replay = 1,
onBufferOverflow = BufferOverflow.DROP_OLDEST,
)
@ -171,7 +170,7 @@ internal class WcPairModel @Inject constructor(
private suspend fun handlePairState(
pairState: WcPairState,
portfolios: PortfolioFetcher.Data? = null,
selected: Pair<UserWallet, AccountStatus>? = null,
selected: Pair<UserWallet, AccountStatus.CryptoPortfolio>? = null,
isAccountMode: Boolean? = null,
) {
when (pairState) {
@ -206,7 +205,7 @@ internal class WcPairModel @Inject constructor(
private suspend fun handleProposalState(
pairState: WcPairState.Proposal,
portfolios: PortfolioFetcher.Data? = null,
selected: Pair<UserWallet, AccountStatus>? = null,
selected: Pair<UserWallet, AccountStatus.CryptoPortfolio>? = null,
) {
val availableWallets = pairState.dAppSession.proposalNetwork.keys
.filter { !it.isLocked && it.isMultiCurrency }
@ -266,7 +265,7 @@ internal class WcPairModel @Inject constructor(
}
private suspend fun tryToCreatePortfolioSelectRow(
selectedPortfolio: Pair<UserWallet, AccountStatus>?,
selectedPortfolio: Pair<UserWallet, AccountStatus.CryptoPortfolio>?,
portfolios: PortfolioFetcher.Data?,
): PortfolioSelectUM? {
selectedPortfolio ?: return null
@ -274,7 +273,6 @@ internal class WcPairModel @Inject constructor(
val (wallet, portfolioAccount) = selectedPortfolio
val account = when (val account = portfolioAccount.account) {
is Account.CryptoPortfolio -> account
is Account.Payment -> TODO("[REDACTED_JIRA]")
}
val isAccountMode = selectorController.isAccountMode.first()
val icon: AccountIconUM.CryptoPortfolio?

View file

@ -48,7 +48,7 @@ internal class WcSessionsAccountModeTransformer(
)
items.add(walletHeader)
accountList.accounts.forEach accountsForEach@{ account ->
accountList.accounts.filterIsInstance<Account.CryptoPortfolio>().forEach accountsForEach@{ account ->
val accountSessions = sessions.filter { it.account?.accountId == account.accountId }
if (accountSessions.isEmpty()) return@accountsForEach
val connectedApps = accountSessions.map { dappSession ->
@ -65,7 +65,6 @@ internal class WcSessionsAccountModeTransformer(
}
val accountIcon = when (account) {
is Account.CryptoPortfolio -> account.icon
is Account.Payment -> TODO("[REDACTED_JIRA]")
}
val accountTitle = AccountTitleUM.Account(

View file

@ -19,13 +19,12 @@ internal class WcPortfolioNameDelegate @AssistedInject constructor(
isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase,
@Assisted private val scope: CoroutineScope,
) {
val isAccountMode = isAccountsModeEnabledUseCase.invoke()
private val isAccountMode = isAccountsModeEnabledUseCase.invoke()
.stateIn(scope = scope, started = SharingStarted.Eagerly, initialValue = false)
fun createAccountTitleUM(value: WcSession): AccountTitleUM? {
val account = when (val account = value.account) {
is Account.CryptoPortfolio -> account
is Account.Payment -> TODO("[REDACTED_JIRA]")
null -> null
}

View file

@ -11,7 +11,6 @@ import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.decompose.navigation.Router
import com.tangem.core.decompose.ui.UiMessageSender
import com.tangem.core.ui.clipboard.ClipboardManager
import com.tangem.domain.models.account.derivationIndex
import com.tangem.domain.walletconnect.WcAnalyticEvents
import com.tangem.domain.walletconnect.WcRequestUseCaseFactory
import com.tangem.domain.walletconnect.usecase.method.WcAddNetworkUseCase

View file

@ -23,7 +23,6 @@ import com.tangem.core.ui.components.bottomsheets.message.MessageBottomSheetUMV2
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.wrappedList
import com.tangem.domain.core.lce.Lce
import com.tangem.domain.models.account.derivationIndex
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.network.Network
import com.tangem.domain.models.wallet.UserWallet

View file

@ -12,7 +12,6 @@ import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.decompose.navigation.Router
import com.tangem.core.decompose.ui.UiMessageSender
import com.tangem.core.ui.clipboard.ClipboardManager
import com.tangem.domain.models.account.derivationIndex
import com.tangem.domain.walletconnect.WcAnalyticEvents
import com.tangem.domain.walletconnect.WcRequestUseCaseFactory
import com.tangem.domain.walletconnect.model.WcEthMethod