Updated on 2026-08-14
This commit is contained in:
parent
24d7953389
commit
8683516c59
24 changed files with 817 additions and 148 deletions
|
|
@ -3,7 +3,6 @@ package com.tangem.domain.account.status.producer
|
|||
import arrow.core.Option
|
||||
import arrow.core.none
|
||||
import arrow.core.toOption
|
||||
import com.tangem.common.card.FirmwareVersion
|
||||
import com.tangem.core.analytics.api.AnalyticsExceptionHandler
|
||||
import com.tangem.domain.account.models.AccountCurrencyId
|
||||
import com.tangem.domain.account.models.AccountList
|
||||
|
|
@ -16,9 +15,7 @@ import com.tangem.domain.core.utils.lceContent
|
|||
import com.tangem.domain.core.utils.lceLoading
|
||||
import com.tangem.domain.models.StatusSource
|
||||
import com.tangem.domain.models.TotalFiatBalance
|
||||
import com.tangem.domain.models.account.Account
|
||||
import com.tangem.domain.models.account.AccountStatus
|
||||
import com.tangem.domain.models.account.VirtualAccountStatusValue
|
||||
import com.tangem.domain.models.account.*
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.network.Network
|
||||
|
|
@ -45,7 +42,7 @@ import com.tangem.domain.tokens.operations.CryptoCurrencyStatusFactory
|
|||
import com.tangem.domain.tokens.operations.PriceChangeCalculator
|
||||
import com.tangem.domain.tokens.operations.TokenListFactory
|
||||
import com.tangem.domain.tokens.operations.TotalFiatBalanceCalculator
|
||||
import com.tangem.hot.sdk.model.HotWalletId
|
||||
import com.tangem.domain.virtualaccount.flow.VirtualAccountStatusSupplier
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.logging.TangemLogger
|
||||
import dagger.assisted.Assisted
|
||||
|
|
@ -83,6 +80,7 @@ internal class DefaultSingleAccountStatusListProducer @AssistedInject constructo
|
|||
private val userWalletsListRepository: UserWalletsListRepository,
|
||||
private val singleAccountListSupplier: SingleAccountListSupplier,
|
||||
private val paymentAccountStatusSupplier: PaymentAccountStatusSupplier,
|
||||
private val virtualAccountStatusSupplier: VirtualAccountStatusSupplier,
|
||||
private val networksRepository: NetworksRepository,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
private val networkStatusSupplier: MultiNetworkStatusSupplier,
|
||||
|
|
@ -93,8 +91,8 @@ internal class DefaultSingleAccountStatusListProducer @AssistedInject constructo
|
|||
) : SingleAccountStatusListProducer {
|
||||
|
||||
private val logger = TangemLogger.withTag(TAG)
|
||||
|
||||
// VirtualAccount status pipeline lands in a follow-up PR; until then surface an unavailable status.
|
||||
private val Account.Payment.errorPaymentAccountStatus: AccountStatus.Payment
|
||||
get() = AccountStatus.Payment(this, PaymentAccountStatusValue.Error.Unavailable)
|
||||
private val Account.Virtual.errorVirtualAccountStatus: AccountStatus.Virtual
|
||||
get() = AccountStatus.Virtual(this, VirtualAccountStatusValue.Error.Unavailable)
|
||||
|
||||
|
|
@ -148,141 +146,100 @@ internal class DefaultSingleAccountStatusListProducer @AssistedInject constructo
|
|||
flattenCurrency = flattenCurrency,
|
||||
)
|
||||
|
||||
val isPaymentSupported = userWallet.isPaymentAccountSupported()
|
||||
logger.i("flattenFlow[$walletId]: isPaymentAccountSupported=$isPaymentSupported")
|
||||
if (isPaymentSupported) {
|
||||
combineWithPaymentAccount(
|
||||
accountListFlow = accountListFlow,
|
||||
cryptoCurrencyStatusFlow = cryptoCurrencyStatusFlow,
|
||||
paymentAccountStatusFlow = paymentAccountStatusSupplier.invoke(userWalletId = params.userWalletId)
|
||||
.onEach { paymentStatus ->
|
||||
logger.i(
|
||||
"flattenFlow[$walletId]: paymentAccountStatus emitted " +
|
||||
"valueType=${paymentStatus.value::class.simpleName}",
|
||||
)
|
||||
},
|
||||
)
|
||||
} else {
|
||||
combineWithoutPaymentAccount(
|
||||
accountListFlow = accountListFlow,
|
||||
cryptoCurrencyStatusFlow = cryptoCurrencyStatusFlow,
|
||||
)
|
||||
}
|
||||
.collect { accountStatusList -> channel.send(accountStatusList) }
|
||||
}
|
||||
|
||||
private fun combineWithPaymentAccount(
|
||||
accountListFlow: StateFlow<AccountList>,
|
||||
cryptoCurrencyStatusFlow: Flow<Map<AccountCurrencyId, CryptoCurrencyStatus>>,
|
||||
paymentAccountStatusFlow: Flow<AccountStatus.Payment>,
|
||||
): Flow<AccountStatusList> {
|
||||
return combine(
|
||||
flow = accountListFlow,
|
||||
flow2 = cryptoCurrencyStatusFlow,
|
||||
flow3 = paymentAccountStatusFlow,
|
||||
transform = { accountList, currencyStatusMap, paymentAccountStatus ->
|
||||
logger.i(
|
||||
"combineWithPayment[${params.userWalletId}] transform: " +
|
||||
"accounts=${accountList.accounts.size}, " +
|
||||
"currencyStatusMap=${currencyStatusMap.size}, " +
|
||||
"paymentType=${paymentAccountStatus.value::class.simpleName}",
|
||||
)
|
||||
val accountStatuses = accountList.accounts.map { account ->
|
||||
when (account) {
|
||||
is Account.Payment -> paymentAccountStatus
|
||||
is Account.Virtual -> account.errorVirtualAccountStatus
|
||||
is Account.CryptoPortfolio -> if (account.cryptoCurrencies.isEmpty()) {
|
||||
account.toEmptyAccountStatus()
|
||||
} else {
|
||||
val statuses: List<CryptoCurrencyStatus> =
|
||||
account.cryptoCurrencies.map { currency ->
|
||||
val acId = account.accountId to currency.id
|
||||
currencyStatusMap[acId] ?: currency.toLoadingCurrencyStatus()
|
||||
}
|
||||
AccountStatus.CryptoPortfolio(
|
||||
account = account,
|
||||
tokenList = TokenListFactory.create(
|
||||
statuses = statuses,
|
||||
groupType = accountList.groupType,
|
||||
sortType = accountList.sortType,
|
||||
),
|
||||
priceChangeLce = PriceChangeCalculator.calculate(statuses = statuses),
|
||||
val accounts = accountListFlow.value.accounts
|
||||
val hasPaymentAccount = accounts.any { it is Account.Payment }
|
||||
val hasVirtualAccount = accounts.any { it is Account.Virtual }
|
||||
logger.i("flattenFlow[$walletId]: payment=$hasPaymentAccount, virtual=$hasVirtualAccount")
|
||||
val specialStatusFlows = buildList<Flow<AccountStatus>> {
|
||||
if (hasPaymentAccount) {
|
||||
add(
|
||||
paymentAccountStatusSupplier.invoke(userWalletId = walletId)
|
||||
.onEach { status ->
|
||||
logger.i(
|
||||
"flattenFlow[$walletId]: paymentAccountStatus emitted " +
|
||||
"valueType=${status.value::class.simpleName}",
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
if (hasVirtualAccount) {
|
||||
add(
|
||||
virtualAccountStatusSupplier.invoke(userWalletId = walletId)
|
||||
.onEach { status ->
|
||||
logger.i(
|
||||
"flattenFlow[$walletId]: virtualAccountStatus emitted " +
|
||||
"valueType=${status.value::class.simpleName}",
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
val specialStatusesFlow: Flow<Map<AccountId, AccountStatus>> = if (specialStatusFlows.isEmpty()) {
|
||||
flowOf(emptyMap())
|
||||
} else {
|
||||
combine(specialStatusFlows) { statuses -> statuses.associateBy(AccountStatus::accountId) }
|
||||
}
|
||||
|
||||
combine(
|
||||
accountListFlow,
|
||||
cryptoCurrencyStatusFlow,
|
||||
specialStatusesFlow,
|
||||
) { accountList, currencyStatusMap, specialStatuses ->
|
||||
logger.i(
|
||||
"combine[$walletId] transform:" +
|
||||
"accounts=${accountList.accounts.size}, " +
|
||||
"currencyStatusMap=${currencyStatusMap.size}, " +
|
||||
"specialStatuses=${specialStatuses.size}",
|
||||
)
|
||||
val accountStatuses = accountList.accounts.map { account ->
|
||||
when (account) {
|
||||
is Account.CryptoPortfolio -> buildCryptoPortfolioStatus(account, currencyStatusMap, accountList)
|
||||
is Account.Payment -> specialStatuses[account.accountId] ?: account.errorPaymentAccountStatus
|
||||
is Account.Virtual -> specialStatuses[account.accountId] ?: account.errorVirtualAccountStatus
|
||||
}
|
||||
val balances = accountStatuses.flattenTotalFiatBalance()
|
||||
}
|
||||
buildAccountStatusList(accountList = accountList, accountStatuses = accountStatuses)
|
||||
}.collect { accountStatusList -> channel.send(accountStatusList) }
|
||||
}
|
||||
|
||||
AccountStatusList(
|
||||
userWalletId = accountList.userWalletId,
|
||||
accountStatuses = accountStatuses,
|
||||
totalAccounts = accountList.totalAccounts,
|
||||
totalFiatBalance = TotalFiatBalanceCalculator.calculate(balances),
|
||||
totalArchivedAccounts = accountList.totalArchivedAccounts,
|
||||
sortType = accountList.sortType,
|
||||
groupType = accountList.groupType,
|
||||
)
|
||||
},
|
||||
private fun buildCryptoPortfolioStatus(
|
||||
account: Account.CryptoPortfolio,
|
||||
currencyStatusMap: Map<AccountCurrencyId, CryptoCurrencyStatus>,
|
||||
accountList: AccountList,
|
||||
): AccountStatus.CryptoPortfolio {
|
||||
if (account.cryptoCurrencies.isEmpty()) return account.toEmptyAccountStatus()
|
||||
|
||||
val statuses: List<CryptoCurrencyStatus> = account.cryptoCurrencies.map { currency ->
|
||||
val acId = account.accountId to currency.id
|
||||
currencyStatusMap[acId] ?: currency.toLoadingCurrencyStatus()
|
||||
}
|
||||
return AccountStatus.CryptoPortfolio(
|
||||
account = account,
|
||||
tokenList = TokenListFactory.create(
|
||||
statuses = statuses,
|
||||
groupType = accountList.groupType,
|
||||
sortType = accountList.sortType,
|
||||
),
|
||||
priceChangeLce = PriceChangeCalculator.calculate(statuses = statuses),
|
||||
)
|
||||
}
|
||||
|
||||
private fun combineWithoutPaymentAccount(
|
||||
accountListFlow: StateFlow<AccountList>,
|
||||
cryptoCurrencyStatusFlow: Flow<Map<AccountCurrencyId, CryptoCurrencyStatus>>,
|
||||
): Flow<AccountStatusList> {
|
||||
return combine(
|
||||
flow = accountListFlow,
|
||||
flow2 = cryptoCurrencyStatusFlow,
|
||||
transform = { accountList, currencyStatusMap ->
|
||||
logger.i(
|
||||
"combineWithoutPayment[${params.userWalletId}] transform: " +
|
||||
"accounts=${accountList.accounts.size}, " +
|
||||
"currencyStatusMap=${currencyStatusMap.size}",
|
||||
)
|
||||
val accountStatuses = accountList.accounts
|
||||
.filterIsInstance<Account.CryptoPortfolio>()
|
||||
.map { account ->
|
||||
when (account) {
|
||||
is Account.CryptoPortfolio -> if (account.cryptoCurrencies.isEmpty()) {
|
||||
account.toEmptyAccountStatus()
|
||||
} else {
|
||||
val statuses: List<CryptoCurrencyStatus> =
|
||||
account.cryptoCurrencies.map { currency ->
|
||||
val acId = account.accountId to currency.id
|
||||
currencyStatusMap[acId] ?: currency.toLoadingCurrencyStatus()
|
||||
}
|
||||
AccountStatus.CryptoPortfolio(
|
||||
account = account,
|
||||
tokenList = TokenListFactory.create(
|
||||
statuses = statuses,
|
||||
groupType = accountList.groupType,
|
||||
sortType = accountList.sortType,
|
||||
),
|
||||
priceChangeLce = PriceChangeCalculator.calculate(statuses = statuses),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
val balances = accountStatuses.flattenTotalFiatBalance()
|
||||
|
||||
AccountStatusList(
|
||||
userWalletId = accountList.userWalletId,
|
||||
accountStatuses = accountStatuses,
|
||||
totalAccounts = accountList.totalAccounts,
|
||||
totalFiatBalance = TotalFiatBalanceCalculator.calculate(balances),
|
||||
totalArchivedAccounts = accountList.totalArchivedAccounts,
|
||||
sortType = accountList.sortType,
|
||||
groupType = accountList.groupType,
|
||||
)
|
||||
},
|
||||
private fun buildAccountStatusList(
|
||||
accountList: AccountList,
|
||||
accountStatuses: List<AccountStatus>,
|
||||
): AccountStatusList {
|
||||
val balances = accountStatuses.flattenTotalFiatBalance()
|
||||
return AccountStatusList(
|
||||
userWalletId = accountList.userWalletId,
|
||||
accountStatuses = accountStatuses,
|
||||
totalAccounts = accountList.totalAccounts,
|
||||
totalFiatBalance = TotalFiatBalanceCalculator.calculate(balances),
|
||||
totalArchivedAccounts = accountList.totalArchivedAccounts,
|
||||
sortType = accountList.sortType,
|
||||
groupType = accountList.groupType,
|
||||
)
|
||||
}
|
||||
|
||||
private fun UserWallet.isPaymentAccountSupported(): Boolean = when (this) {
|
||||
is UserWallet.Cold -> scanResponse.card.firmwareVersion >= FirmwareVersion.HDWalletAvailable
|
||||
is UserWallet.Hot -> hotWalletId.authType != HotWalletId.AuthType.NoPassword
|
||||
}
|
||||
|
||||
private fun ProducerScope<AccountStatusList>.flattenCurrencyStatusFlow(
|
||||
userWallet: UserWallet,
|
||||
flattenCurrency: MutableSharedFlow<Map<AccountCurrencyId, CryptoCurrency>>,
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ dependencies {
|
|||
implementation(projects.features.staking.api)
|
||||
implementation(projects.features.markets.api)
|
||||
implementation(projects.features.swap.api)
|
||||
implementation(projects.features.virtualAccounts.details.api) //VIRTUAL_ACCOUNTS_ENABLED
|
||||
|
||||
/** Project - Other */
|
||||
implementation(projects.core.configToggles)
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesSupplier
|
|||
import com.tangem.domain.tokens.wallet.implementor.MultiWalletBalanceFetcher
|
||||
import com.tangem.domain.tokens.wallet.implementor.SingleWalletBalanceFetcher
|
||||
import com.tangem.domain.tokens.wallet.implementor.SingleWalletWithTokenBalanceFetcher
|
||||
import com.tangem.domain.virtualaccount.flow.VirtualAccountStatusFetcher
|
||||
import com.tangem.features.virtualaccount.VirtualAccountFeatureToggles
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.logging.TangemLogger
|
||||
import kotlinx.coroutines.async
|
||||
|
|
@ -56,6 +58,8 @@ class WalletBalanceFetcher internal constructor(
|
|||
private val singleWalletBalanceFetcher: BaseWalletBalanceFetcher,
|
||||
private val balanceFetchingOperations: BalanceFetchingOperations,
|
||||
private val paymentAccountStatusFetcher: PaymentAccountStatusFetcher,
|
||||
private val virtualAccountStatusFetcher: VirtualAccountStatusFetcher,
|
||||
private val virtualAccountsFeatureToggles: VirtualAccountFeatureToggles,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
) : FlowFetcher<WalletBalanceFetcher.Params> {
|
||||
|
||||
|
|
@ -70,7 +74,9 @@ class WalletBalanceFetcher internal constructor(
|
|||
multiQuoteStatusFetcher: MultiQuoteStatusFetcher,
|
||||
multiStakingBalanceFetcher: MultiStakingBalanceFetcher,
|
||||
paymentAccountStatusFetcher: PaymentAccountStatusFetcher,
|
||||
virtualAccountStatusFetcher: VirtualAccountStatusFetcher,
|
||||
stakingIdFactory: StakingIdFactory,
|
||||
virtualAccountsFeatureToggles: VirtualAccountFeatureToggles,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
) : this(
|
||||
userWalletsListRepository = userWalletsListRepository,
|
||||
|
|
@ -85,6 +91,8 @@ class WalletBalanceFetcher internal constructor(
|
|||
stakingIdFactory = stakingIdFactory,
|
||||
),
|
||||
paymentAccountStatusFetcher = paymentAccountStatusFetcher,
|
||||
virtualAccountStatusFetcher = virtualAccountStatusFetcher,
|
||||
virtualAccountsFeatureToggles = virtualAccountsFeatureToggles,
|
||||
dispatchers = dispatchers,
|
||||
)
|
||||
|
||||
|
|
@ -99,6 +107,8 @@ class WalletBalanceFetcher internal constructor(
|
|||
multiQuoteStatusFetcher: MultiQuoteStatusFetcher,
|
||||
multiStakingBalanceFetcher: MultiStakingBalanceFetcher,
|
||||
paymentAccountStatusFetcher: PaymentAccountStatusFetcher,
|
||||
virtualAccountStatusFetcher: VirtualAccountStatusFetcher,
|
||||
virtualAccountsFeatureToggles: VirtualAccountFeatureToggles,
|
||||
stakingIdFactory: StakingIdFactory,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
) : this(
|
||||
|
|
@ -121,6 +131,8 @@ class WalletBalanceFetcher internal constructor(
|
|||
stakingIdFactory = stakingIdFactory,
|
||||
),
|
||||
paymentAccountStatusFetcher = paymentAccountStatusFetcher,
|
||||
virtualAccountStatusFetcher = virtualAccountStatusFetcher,
|
||||
virtualAccountsFeatureToggles = virtualAccountsFeatureToggles,
|
||||
dispatchers = dispatchers,
|
||||
)
|
||||
|
||||
|
|
@ -177,6 +189,14 @@ class WalletBalanceFetcher internal constructor(
|
|||
balanceFetchingOperations.fetchQuotes(rawCurrencyIds = setOf(TangemPayCurrencyFactory.TOKEN_ID))
|
||||
paymentAccountStatusFetcher.invoke(PaymentAccountStatusFetcher.Params(userWalletId))
|
||||
}
|
||||
|
||||
// Fetch Virtual account separately for the same reason as TangemPay
|
||||
if (
|
||||
fetchingSources.any { it is WalletFetchingSource.VirtualAccount } &&
|
||||
virtualAccountsFeatureToggles.isVirtualAccountsEnabled
|
||||
) {
|
||||
virtualAccountStatusFetcher.invoke(VirtualAccountStatusFetcher.Params(userWalletId))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,13 @@ sealed class WalletFetchingSource {
|
|||
*/
|
||||
data object TangemPay : WalletFetchingSource()
|
||||
|
||||
/**
|
||||
* Virtual account fetching source.
|
||||
* Handled separately from standard balance sources via
|
||||
* [com.tangem.domain.virtualaccount.flow.VirtualAccountStatusFetcher].
|
||||
*/
|
||||
data object VirtualAccount : WalletFetchingSource()
|
||||
|
||||
/**
|
||||
* Standard balance fetching sources (NETWORK, QUOTE, STAKING).
|
||||
* Processed via [BalanceFetchingOperations.fetchAll].
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ internal class MultiWalletBalanceFetcher(
|
|||
sources = setOf(FetchingSource.NETWORK, FetchingSource.QUOTE, FetchingSource.STAKING),
|
||||
),
|
||||
WalletFetchingSource.TangemPay,
|
||||
WalletFetchingSource.VirtualAccount,
|
||||
)
|
||||
|
||||
override suspend fun getCryptoCurrencies(userWallet: UserWallet): Set<CryptoCurrency> {
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@ import com.tangem.domain.tokens.FetchingSource
|
|||
import com.tangem.domain.tokens.wallet.implementor.MultiWalletBalanceFetcher
|
||||
import com.tangem.domain.tokens.wallet.implementor.SingleWalletBalanceFetcher
|
||||
import com.tangem.domain.tokens.wallet.implementor.SingleWalletWithTokenBalanceFetcher
|
||||
import com.tangem.domain.virtualaccount.flow.VirtualAccountStatusFetcher
|
||||
import com.tangem.features.virtualaccount.VirtualAccountFeatureToggles
|
||||
import com.tangem.test.core.assertEither
|
||||
import com.tangem.test.core.assertEitherRight
|
||||
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
|
||||
|
|
@ -50,7 +52,11 @@ internal class WalletBalanceFetcherTest {
|
|||
private val multiQuoteStatusFetcher: MultiQuoteStatusFetcher = mockk()
|
||||
private val multiStakingBalanceFetcher: MultiStakingBalanceFetcher = mockk()
|
||||
private val paymentAccountStatusFetcher: PaymentAccountStatusFetcher = mockk()
|
||||
private val virtualAccountStatusFetcher: VirtualAccountStatusFetcher = mockk()
|
||||
private val stakingIdFactory: StakingIdFactory = mockk()
|
||||
private val virtualAccountsFeatureToggles: VirtualAccountFeatureToggles = mockk {
|
||||
every { isVirtualAccountsEnabled } returns false
|
||||
}
|
||||
|
||||
private val fetcher = WalletBalanceFetcher(
|
||||
userWalletsListRepository = userWalletsListRepository,
|
||||
|
|
@ -62,7 +68,9 @@ internal class WalletBalanceFetcherTest {
|
|||
multiQuoteStatusFetcher = multiQuoteStatusFetcher,
|
||||
multiStakingBalanceFetcher = multiStakingBalanceFetcher,
|
||||
paymentAccountStatusFetcher = paymentAccountStatusFetcher,
|
||||
virtualAccountStatusFetcher = virtualAccountStatusFetcher,
|
||||
stakingIdFactory = stakingIdFactory,
|
||||
virtualAccountsFeatureToggles = virtualAccountsFeatureToggles,
|
||||
dispatchers = TestingCoroutineDispatcherProvider(),
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -7,10 +7,10 @@ import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory
|
|||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.tokens.FetchingSource
|
||||
import com.tangem.domain.tokens.MultiWalletAccountListFetcher
|
||||
import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesProducer
|
||||
import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesSupplier
|
||||
import com.tangem.domain.tokens.FetchingSource
|
||||
import com.tangem.domain.tokens.wallet.WalletFetchingSource
|
||||
import io.mockk.clearMocks
|
||||
import io.mockk.coEvery
|
||||
|
|
@ -54,6 +54,7 @@ class MultiWalletBalanceFetcherTest {
|
|||
sources = setOf(FetchingSource.NETWORK, FetchingSource.QUOTE, FetchingSource.STAKING),
|
||||
),
|
||||
WalletFetchingSource.TangemPay,
|
||||
WalletFetchingSource.VirtualAccount,
|
||||
)
|
||||
Truth.assertThat(actual).isEqualTo(expected)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
package com.tangem.domain.virtualaccount.flow
|
||||
|
||||
import arrow.core.Either
|
||||
import com.tangem.domain.core.flow.FlowFetcher
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
|
||||
interface VirtualAccountStatusFetcher : FlowFetcher<VirtualAccountStatusFetcher.Params> {
|
||||
|
||||
suspend operator fun invoke(userWalletId: UserWalletId): Either<Throwable, Unit> {
|
||||
return invoke(Params(userWalletId))
|
||||
}
|
||||
|
||||
data class Params(val userWalletId: UserWalletId)
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package com.tangem.domain.virtualaccount.flow
|
||||
|
||||
import com.tangem.domain.core.flow.FlowProducer
|
||||
import com.tangem.domain.models.account.AccountStatus
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
|
||||
interface VirtualAccountStatusProducer : FlowProducer<AccountStatus.Virtual> {
|
||||
data class Params(val userWalletId: UserWalletId)
|
||||
|
||||
interface Factory : FlowProducer.Factory<Params, VirtualAccountStatusProducer>
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package com.tangem.domain.virtualaccount.flow
|
||||
|
||||
import com.tangem.domain.core.flow.FlowCachingSupplier
|
||||
import com.tangem.domain.models.account.AccountStatus
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
open class VirtualAccountStatusSupplier(
|
||||
override val factory: VirtualAccountStatusProducer.Factory,
|
||||
override val keyCreator: (VirtualAccountStatusProducer.Params) -> String,
|
||||
) : FlowCachingSupplier<VirtualAccountStatusProducer, VirtualAccountStatusProducer.Params, AccountStatus.Virtual>() {
|
||||
|
||||
operator fun invoke(userWalletId: UserWalletId): Flow<AccountStatus.Virtual> {
|
||||
val params = VirtualAccountStatusProducer.Params(userWalletId)
|
||||
return this.invoke(params)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue