Updated on 2026-08-14
This commit is contained in:
parent
dcaae36f60
commit
c6578aa652
27 changed files with 111 additions and 1782 deletions
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.feature.referral.domain
|
||||
|
||||
import com.tangem.domain.models.PortfolioId
|
||||
import com.tangem.domain.models.account.AccountId
|
||||
import com.tangem.domain.models.account.DerivationIndex
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
|
|
@ -11,7 +11,7 @@ interface ReferralInteractor {
|
|||
|
||||
suspend fun getReferralStatus(userWalletId: UserWalletId): ReferralData
|
||||
|
||||
suspend fun startReferral(portfolioId: PortfolioId): ReferralData
|
||||
suspend fun startReferral(accountId: AccountId): ReferralData
|
||||
|
||||
suspend fun getCryptoCurrency(
|
||||
userWalletId: UserWalletId,
|
||||
|
|
|
|||
|
|
@ -1,30 +1,22 @@
|
|||
package com.tangem.feature.referral.domain
|
||||
|
||||
import arrow.core.getOrElse
|
||||
import com.tangem.common.core.TangemSdkError
|
||||
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.AccountId
|
||||
import com.tangem.domain.models.account.DerivationIndex
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.tokens.AddCryptoCurrenciesUseCase
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
import com.tangem.domain.wallets.usecase.DerivePublicKeysUseCase
|
||||
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
||||
import com.tangem.feature.referral.domain.errors.ReferralError
|
||||
import com.tangem.feature.referral.domain.models.ReferralData
|
||||
import com.tangem.feature.referral.domain.models.TokenData
|
||||
import timber.log.Timber
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
internal class ReferralInteractorImpl(
|
||||
private val repository: ReferralRepository,
|
||||
private val derivePublicKeysUseCase: DerivePublicKeysUseCase,
|
||||
private val getUserWalletUseCase: GetUserWalletUseCase,
|
||||
private val addCryptoCurrenciesUseCase: AddCryptoCurrenciesUseCase,
|
||||
private val manageCryptoCurrenciesUseCase: ManageCryptoCurrenciesUseCase,
|
||||
private val singleAccountSupplier: SingleAccountSupplier,
|
||||
private val walletManagersFacade: WalletManagersFacade,
|
||||
|
|
@ -40,64 +32,41 @@ internal class ReferralInteractorImpl(
|
|||
return referralData
|
||||
}
|
||||
|
||||
override suspend fun startReferral(portfolioId: PortfolioId): ReferralData {
|
||||
override suspend fun startReferral(accountId: AccountId): ReferralData {
|
||||
if (tokensForReferral.isEmpty()) error("Tokens for ref is empty")
|
||||
|
||||
val tokenData = tokensForReferral.first()
|
||||
val userWalletId = portfolioId.userWalletId
|
||||
val userWallet = getUserWalletUseCase(userWalletId).getOrElse {
|
||||
error("Failed to get user wallet $userWalletId: $it")
|
||||
}
|
||||
val userWalletId = accountId.userWalletId
|
||||
|
||||
val accountIndex = when (portfolioId) {
|
||||
is PortfolioId.Account -> {
|
||||
val account = singleAccountSupplier.getSyncOrNull(
|
||||
params = SingleAccountProducer.Params(accountId = portfolioId.accountId),
|
||||
)
|
||||
?: error("Account not found: ${portfolioId.accountId}")
|
||||
val account = singleAccountSupplier.getSyncOrNull(
|
||||
params = SingleAccountProducer.Params(accountId = accountId),
|
||||
)
|
||||
?: error("Account not found: $accountId")
|
||||
|
||||
when (account) {
|
||||
is Account.CryptoPortfolio -> account.derivationIndex
|
||||
is Account.Payment -> TODO("[REDACTED_JIRA]")
|
||||
}
|
||||
}
|
||||
is PortfolioId.Wallet -> null
|
||||
val accountIndex = when (account) {
|
||||
is Account.CryptoPortfolio -> account.derivationIndex
|
||||
is Account.Payment -> TODO("[REDACTED_JIRA]")
|
||||
}
|
||||
|
||||
val cryptoCurrency = getCryptoCurrency(
|
||||
userWalletId = portfolioId.userWalletId,
|
||||
userWalletId = accountId.userWalletId,
|
||||
tokenData = tokenData,
|
||||
accountIndex = accountIndex,
|
||||
)
|
||||
?: error("Failed to create crypto currency")
|
||||
|
||||
when (portfolioId) {
|
||||
is PortfolioId.Account -> {
|
||||
manageCryptoCurrenciesUseCase(
|
||||
accountId = portfolioId.accountId,
|
||||
add = cryptoCurrency,
|
||||
skipDerivationErrors = false,
|
||||
).mapLeft {
|
||||
it.mapToDomainError()
|
||||
}.onLeft { error ->
|
||||
if (error is ReferralError.UserCancelledException) {
|
||||
throw error
|
||||
}
|
||||
manageCryptoCurrenciesUseCase(
|
||||
accountId = accountId,
|
||||
add = cryptoCurrency,
|
||||
skipDerivationErrors = false,
|
||||
)
|
||||
.mapLeft { it.mapToDomainError() }
|
||||
.onLeft { error ->
|
||||
Timber.e(error)
|
||||
if (error is ReferralError.UserCancelledException) {
|
||||
throw error
|
||||
}
|
||||
}
|
||||
is PortfolioId.Wallet -> {
|
||||
derivePublicKeysUseCase(userWallet.walletId, listOf(cryptoCurrency)).getOrElse { throwable ->
|
||||
Timber.e("Failed to derive public keys: $throwable")
|
||||
throw throwable.mapToDomainError()
|
||||
}
|
||||
|
||||
addCryptoCurrenciesUseCase(
|
||||
userWalletId = userWallet.walletId,
|
||||
currency = cryptoCurrency,
|
||||
)
|
||||
}
|
||||
}
|
||||
.onLeft(Timber::e)
|
||||
|
||||
val publicAddress = walletManagersFacade.getDefaultAddress(
|
||||
userWalletId = userWalletId,
|
||||
|
|
|
|||
|
|
@ -4,10 +4,7 @@ import com.tangem.core.decompose.di.ModelComponent
|
|||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.domain.account.status.usecase.ManageCryptoCurrenciesUseCase
|
||||
import com.tangem.domain.account.supplier.SingleAccountSupplier
|
||||
import com.tangem.domain.tokens.AddCryptoCurrenciesUseCase
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
import com.tangem.domain.wallets.usecase.DerivePublicKeysUseCase
|
||||
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
||||
import com.tangem.feature.referral.domain.ReferralInteractor
|
||||
import com.tangem.feature.referral.domain.ReferralInteractorImpl
|
||||
import com.tangem.feature.referral.domain.ReferralRepository
|
||||
|
|
@ -23,18 +20,12 @@ class ReferralDomainModule {
|
|||
@ModelScoped
|
||||
fun provideReferralInteractor(
|
||||
referralRepository: ReferralRepository,
|
||||
derivePublicKeysUseCase: DerivePublicKeysUseCase,
|
||||
getUserWalletUseCase: GetUserWalletUseCase,
|
||||
addCryptoCurrenciesUseCase: AddCryptoCurrenciesUseCase,
|
||||
manageCryptoCurrenciesUseCase: ManageCryptoCurrenciesUseCase,
|
||||
singleAccountSupplier: SingleAccountSupplier,
|
||||
walletManagersFacade: WalletManagersFacade,
|
||||
): ReferralInteractor {
|
||||
return ReferralInteractorImpl(
|
||||
repository = referralRepository,
|
||||
derivePublicKeysUseCase = derivePublicKeysUseCase,
|
||||
getUserWalletUseCase = getUserWalletUseCase,
|
||||
addCryptoCurrenciesUseCase = addCryptoCurrenciesUseCase,
|
||||
manageCryptoCurrenciesUseCase = manageCryptoCurrenciesUseCase,
|
||||
singleAccountSupplier = singleAccountSupplier,
|
||||
walletManagersFacade = walletManagersFacade,
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ import com.tangem.core.decompose.model.Model
|
|||
import com.tangem.core.decompose.model.ParamsContainer
|
||||
import com.tangem.core.navigation.share.ShareManager
|
||||
import com.tangem.core.navigation.url.UrlOpener
|
||||
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
|
||||
import com.tangem.domain.account.models.AccountStatusList
|
||||
import com.tangem.domain.account.status.model.AccountCryptoCurrency
|
||||
import com.tangem.domain.account.status.producer.SingleAccountStatusListProducer
|
||||
|
|
@ -24,8 +23,6 @@ import com.tangem.domain.account.status.usecase.GetAccountCurrencyByAddressUseCa
|
|||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
|
||||
import com.tangem.domain.demo.IsDemoCardUseCase
|
||||
import com.tangem.domain.models.PortfolioId
|
||||
import com.tangem.domain.models.account.AccountStatus
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
||||
|
|
@ -44,10 +41,12 @@ import com.tangem.features.account.PortfolioFetcher
|
|||
import com.tangem.features.account.PortfolioSelectorComponent
|
||||
import com.tangem.features.account.PortfolioSelectorController
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@Suppress("LongParameterList")
|
||||
@Stable
|
||||
@ModelScoped
|
||||
|
|
@ -60,7 +59,6 @@ internal class ReferralModel @Inject constructor(
|
|||
private val urlOpener: UrlOpener,
|
||||
private val getUserWalletUseCase: GetUserWalletUseCase,
|
||||
private val isDemoCardUseCase: IsDemoCardUseCase,
|
||||
private val accountsFeatureToggles: AccountsFeatureToggles,
|
||||
private val portfolioFetcherFactory: PortfolioFetcher.Factory,
|
||||
val portfolioSelectorController: PortfolioSelectorController,
|
||||
private val singleAccountStatusListSupplier: SingleAccountStatusListSupplier,
|
||||
|
|
@ -92,26 +90,24 @@ internal class ReferralModel @Inject constructor(
|
|||
|
||||
init {
|
||||
analyticsEventHandler.send(ReferralEvents.ReferralScreenOpened())
|
||||
if (accountsFeatureToggles.isFeatureEnabled) {
|
||||
combine(
|
||||
flow = referralData.filterNotNull().onEach(::selectAccount),
|
||||
flow2 = portfolioSelectorController.isAccountMode,
|
||||
transform = { referralData, isAccountMode -> referralData to isAccountMode },
|
||||
).transformLatest { (referralData, isAccountMode) ->
|
||||
when (isAccountMode) {
|
||||
false -> showContent(referralData)
|
||||
true -> combineAccountUI(referralData)
|
||||
|
||||
combine(
|
||||
flow = referralData.filterNotNull().onEach(::selectAccount),
|
||||
flow2 = portfolioSelectorController.isAccountMode,
|
||||
transform = { referralData, isAccountMode -> referralData to isAccountMode },
|
||||
)
|
||||
.transformLatest { (referralData, isAccountMode) ->
|
||||
if (!isAccountMode) {
|
||||
showContent(referralData)
|
||||
} else {
|
||||
combineAccountUI(referralData)
|
||||
.map { referralData to it }
|
||||
.collect(::emit)
|
||||
}
|
||||
}
|
||||
.onEach { (referralData, accountAward) -> showContent(referralData, accountAward) }
|
||||
.launchIn(modelScope)
|
||||
} else {
|
||||
referralData.filterNotNull()
|
||||
.onEach(::showContent)
|
||||
.launchIn(modelScope)
|
||||
}
|
||||
.onEach { (referralData, accountAward) -> showContent(referralData, accountAward) }
|
||||
.launchIn(modelScope)
|
||||
|
||||
loadReferralData()
|
||||
}
|
||||
|
||||
|
|
@ -123,12 +119,7 @@ internal class ReferralModel @Inject constructor(
|
|||
flow3 = getSelectedAppCurrencyUseCase.invokeOrDefault(),
|
||||
flow4 = portfolioFetcher.data,
|
||||
) { pair, isBalanceHidden, appCurrency, portfolios ->
|
||||
val selectedAccount = pair?.second ?: return@combine null
|
||||
|
||||
val cryptoPortfolio = when (selectedAccount) {
|
||||
is AccountStatus.CryptoPortfolio -> selectedAccount
|
||||
is AccountStatus.Payment -> TODO("[REDACTED_JIRA]")
|
||||
}
|
||||
val cryptoPortfolio = pair?.second ?: return@combine null
|
||||
|
||||
val awardCryptoCurrency = referralInteractor.getCryptoCurrency(
|
||||
userWalletId = params.userWalletId,
|
||||
|
|
@ -185,11 +176,8 @@ internal class ReferralModel @Inject constructor(
|
|||
val lastInfoState = uiState.referralInfoState
|
||||
uiState = uiState.copy(referralInfoState = ReferralInfoState.Loading)
|
||||
modelScope.launch {
|
||||
val portfolioId = when (accountsFeatureToggles.isFeatureEnabled) {
|
||||
true -> PortfolioId(requireNotNull(portfolioSelectorController.selectedAccountSync))
|
||||
false -> PortfolioId(params.userWalletId)
|
||||
}
|
||||
runCatching { referralInteractor.startReferral(portfolioId) }
|
||||
val accountId = requireNotNull(portfolioSelectorController.selectedAccountSync)
|
||||
runCatching { referralInteractor.startReferral(accountId) }
|
||||
.onSuccess { referral ->
|
||||
analyticsEventHandler.send(ReferralEvents.ParticipateSuccessful())
|
||||
referralData.value = referral
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue