Updated on 2026-08-14

This commit is contained in:
Tangem 2026-01-21 14:21:10 +04:00
parent fc223990a4
commit 9fd13fdc46
11 changed files with 149 additions and 176 deletions

View file

@ -1,15 +1,10 @@
package com.tangem.domain.wallets.repository
import arrow.core.Option
import com.tangem.domain.wallets.models.AppsFlyerConversionData
interface WalletsPromoRepository {
suspend fun getConversionData(): Option<AppsFlyerConversionData>
suspend fun bindRefcodeWithWallets(conversionData: AppsFlyerConversionData)
suspend fun saveConversionData(refcode: String, campaign: String?)
suspend fun bindRefcodeWithWallets(refcode: String, campaign: String?)
suspend fun bindSavedRefcodeWithWallets(): AppsFlyerConversionData
suspend fun retryBindRefcodeWithWallets()
}

View file

@ -1,10 +1,8 @@
package com.tangem.domain.wallets.usecase
import arrow.core.Either
import arrow.core.raise.Raise
import arrow.core.raise.catch
import arrow.core.raise.either
import arrow.core.raise.ensure
import com.tangem.domain.wallets.models.AppsFlyerConversionData
import com.tangem.domain.wallets.repository.WalletsPromoRepository
import kotlinx.coroutines.sync.Mutex
@ -17,59 +15,21 @@ class BindRefcodeWithWalletUseCase @Inject constructor(
private val mutex = Mutex()
suspend operator fun invoke(refcode: String, campaign: String?): Either<Error, Unit> = either {
ensure(refcode.isNotBlank()) { Error.InvalidRefcode }
suspend operator fun invoke(conversionData: AppsFlyerConversionData): Either<Throwable, Unit> = either {
mutex.withLock {
checkSavedRefcode()
bindRefcode(refcode = refcode, campaign = campaign)
saveConversionData(refcode = refcode, campaign = campaign)
catch(
block = { walletsPromoRepository.bindRefcodeWithWallets(conversionData) },
catch = ::raise,
)
}
}
suspend fun retry(): Either<Error, Unit> = either {
suspend fun retry(): Either<Throwable, Unit> = either {
mutex.withLock {
val conversionData = tryBindRefcodeAgain()
saveConversionData(refcode = conversionData.refcode, campaign = conversionData.campaign)
catch(
block = { walletsPromoRepository.retryBindRefcodeWithWallets() },
catch = ::raise,
)
}
}
private suspend fun Raise<Error>.checkSavedRefcode() {
walletsPromoRepository.getConversionData().onSome {
raise(Error.RefcodeAlreadySaved)
}
}
private suspend fun Raise<Error>.bindRefcode(refcode: String, campaign: String?) {
catch(
block = { walletsPromoRepository.bindRefcodeWithWallets(refcode, campaign) },
catch = { raise(Error.DataError(it)) },
)
}
private suspend fun Raise<Error>.tryBindRefcodeAgain(): AppsFlyerConversionData {
return catch(
block = { walletsPromoRepository.bindSavedRefcodeWithWallets() },
catch = { raise(Error.DataError(it)) },
)
}
private suspend fun Raise<Error>.saveConversionData(refcode: String, campaign: String?) {
catch(
block = { walletsPromoRepository.saveConversionData(refcode, campaign) },
catch = { raise(Error.DataError(it)) },
)
}
sealed interface Error {
data object InvalidRefcode : Error
data object RefcodeAlreadySaved : Error
data class DataError(val throwable: Throwable) : Error
}
}