Updated on 2026-08-14

This commit is contained in:
Tangem 2025-10-21 11:27:27 +04:00
parent e07246d25d
commit 9491a9cae6
12 changed files with 82 additions and 50 deletions

View file

@ -9,6 +9,7 @@ import com.tangem.datasource.api.common.response.getOrThrow
import com.tangem.datasource.api.tangemTech.TangemTechApi
import com.tangem.datasource.api.tangemTech.models.StartReferralBody
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.domain.models.account.DerivationIndex
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.feature.referral.converters.ReferralConverter
@ -20,7 +21,6 @@ import kotlinx.coroutines.withContext
import java.util.concurrent.ConcurrentHashMap
import javax.inject.Inject
@Suppress("LongParameterList")
internal class ReferralRepositoryImpl @Inject constructor(
private val referralApi: TangemTechApi,
private val referralConverter: ReferralConverter,
@ -74,7 +74,11 @@ internal class ReferralRepositoryImpl @Inject constructor(
}
}
override suspend fun getCryptoCurrency(userWalletId: UserWalletId, tokenData: TokenData): CryptoCurrency? {
override suspend fun getCryptoCurrency(
userWalletId: UserWalletId,
tokenData: TokenData,
accountIndex: DerivationIndex?,
): CryptoCurrency? {
val userWallet = withContext(coroutineDispatcher.io) {
userWalletsStore.getSyncOrNull(userWalletId) ?: error("Wallet $userWalletId not found")
}
@ -97,12 +101,14 @@ internal class ReferralRepositoryImpl @Inject constructor(
blockchain = blockchain,
extraDerivationPath = null,
userWallet = userWallet,
accountIndex = accountIndex,
)
} else {
cryptoCurrencyFactory.createCoin(
blockchain = blockchain,
extraDerivationPath = null,
userWallet = userWallet,
accountIndex = accountIndex,
)
}
}

View file

@ -1,6 +1,7 @@
package com.tangem.feature.referral.domain
import com.tangem.domain.models.PortfolioId
import com.tangem.domain.models.account.DerivationIndex
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.feature.referral.domain.models.ReferralData
@ -12,5 +13,9 @@ interface ReferralInteractor {
suspend fun startReferral(portfolioId: PortfolioId): ReferralData
suspend fun getCryptoCurrency(userWalletId: UserWalletId, tokenData: TokenData): CryptoCurrency?
suspend fun getCryptoCurrency(
userWalletId: UserWalletId,
tokenData: TokenData,
accountIndex: DerivationIndex?,
): CryptoCurrency?
}

View file

@ -2,8 +2,11 @@ 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.DerivationIndex
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.tokens.AddCryptoCurrenciesUseCase
@ -23,6 +26,7 @@ internal class ReferralInteractorImpl(
private val getUserWalletUseCase: GetUserWalletUseCase,
private val addCryptoCurrenciesUseCase: AddCryptoCurrenciesUseCase,
private val manageCryptoCurrenciesUseCase: ManageCryptoCurrenciesUseCase,
private val singleAccountSupplier: SingleAccountSupplier,
) : ReferralInteractor {
private val tokensForReferral = mutableListOf<TokenData>()
@ -44,7 +48,23 @@ internal class ReferralInteractorImpl(
error("Failed to get user wallet $userWalletId: $it")
}
val cryptoCurrency = repository.getCryptoCurrency(userWalletId = userWallet.walletId, tokenData = tokenData)
val accountIndex = when (portfolioId) {
is PortfolioId.Account -> {
val account = singleAccountSupplier.getSyncOrNull(
params = SingleAccountProducer.Params(accountId = portfolioId.accountId),
)
?: error("Account not found: ${portfolioId.accountId}")
account.derivationIndex
}
is PortfolioId.Wallet -> null
}
val cryptoCurrency = getCryptoCurrency(
userWalletId = portfolioId.userWalletId,
tokenData = tokenData,
accountIndex = accountIndex,
)
?: error("Failed to create crypto currency")
when (portfolioId) {
@ -65,13 +85,10 @@ internal class ReferralInteractorImpl(
}
.onLeft(Timber::e)
val publicAddress = when (portfolioId) {
is PortfolioId.Account -> TODO("account")
is PortfolioId.Wallet -> userWalletManager.getWalletAddress(
networkId = tokenData.networkId,
derivationPath = cryptoCurrency.network.derivationPath.value,
)
}
val publicAddress = userWalletManager.getWalletAddress(
networkId = tokenData.networkId,
derivationPath = cryptoCurrency.network.derivationPath.value,
)
return repository.startReferral(
walletId = userWalletManager.getWalletId(),
@ -81,8 +98,17 @@ internal class ReferralInteractorImpl(
)
}
override suspend fun getCryptoCurrency(userWalletId: UserWalletId, tokenData: TokenData): CryptoCurrency? =
repository.getCryptoCurrency(userWalletId = userWalletId, tokenData = tokenData)
override suspend fun getCryptoCurrency(
userWalletId: UserWalletId,
tokenData: TokenData,
accountIndex: DerivationIndex?,
): CryptoCurrency? {
return repository.getCryptoCurrency(
userWalletId = userWalletId,
tokenData = tokenData,
accountIndex = accountIndex,
)
}
private fun saveReferralTokens(tokens: List<TokenData>) {
tokensForReferral.clear()

View file

@ -1,5 +1,6 @@
package com.tangem.feature.referral.domain
import com.tangem.domain.models.account.DerivationIndex
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.feature.referral.domain.models.ReferralData
@ -16,5 +17,10 @@ interface ReferralRepository {
/** Starts user referral program */
suspend fun startReferral(walletId: String, networkId: String, tokenId: String, address: String): ReferralData
suspend fun getCryptoCurrency(userWalletId: UserWalletId, tokenData: TokenData): CryptoCurrency?
/** Returns [CryptoCurrency] by [tokenData] for specific [userWalletId] and optional [accountIndex] */
suspend fun getCryptoCurrency(
userWalletId: UserWalletId,
tokenData: TokenData,
accountIndex: DerivationIndex?,
): CryptoCurrency?
}

View file

@ -3,6 +3,7 @@ package com.tangem.feature.referral.domain.di
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.wallets.usecase.DerivePublicKeysUseCase
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
@ -27,6 +28,7 @@ class ReferralDomainModule {
getUserWalletUseCase: GetUserWalletUseCase,
addCryptoCurrenciesUseCase: AddCryptoCurrenciesUseCase,
manageCryptoCurrenciesUseCase: ManageCryptoCurrenciesUseCase,
singleAccountSupplier: SingleAccountSupplier,
): ReferralInteractor {
return ReferralInteractorImpl(
repository = referralRepository,
@ -35,6 +37,7 @@ class ReferralDomainModule {
getUserWalletUseCase = getUserWalletUseCase,
addCryptoCurrenciesUseCase = addCryptoCurrenciesUseCase,
manageCryptoCurrenciesUseCase = manageCryptoCurrenciesUseCase,
singleAccountSupplier = singleAccountSupplier,
)
}
}

View file

@ -121,15 +121,20 @@ internal class ReferralModel @Inject constructor(
flow4 = portfolioFetcher.data,
) { pair, isBalanceHidden, appCurrency, portfolios ->
val selectedAccount = pair?.second ?: return@combine null
val awardCryptoCurrency = referralInteractor.getCryptoCurrency(
userWalletId = params.userWalletId,
tokenData = referralData.getToken(),
) ?: return@combine null
val cryptoPortfolio = when (selectedAccount) {
is AccountStatus.CryptoPortfolio -> selectedAccount
}
val awardCryptoCurrency = referralInteractor.getCryptoCurrency(
userWalletId = params.userWalletId,
tokenData = referralData.getToken(),
accountIndex = cryptoPortfolio.account.derivationIndex,
) ?: return@combine null
val accountAwardToken = cryptoPortfolio.tokenList.flattenCurrencies()
.find { it.currency.id == awardCryptoCurrency.id }
return@combine AccountAwardConverter(
isBalanceHidden = isBalanceHidden,
awardCryptoCurrency = awardCryptoCurrency,
@ -142,12 +147,12 @@ internal class ReferralModel @Inject constructor(
}
private fun createInitiallyUiState() = ReferralStateHolder(
headerState = ReferralStateHolder.HeaderState(
headerState = HeaderState(
onBackClicked = appRouter::pop,
),
referralInfoState = ReferralInfoState.Loading,
errorSnackbar = null,
analytics = ReferralStateHolder.Analytics(
analytics = Analytics(
onAgreementClicked = ::onAgreementClicked,
onCopyClicked = ::onCopyClicked,
onShareClicked = ::onShareClicked,