Updated on 2026-08-14

This commit is contained in:
Tangem 2026-01-15 15:20:48 +03:00
parent e45d91b15e
commit fc223990a4
10 changed files with 270 additions and 0 deletions

View file

@ -12,5 +12,7 @@ object DeeplinkConst {
const val DERIVATION_PATH_KEY = "derivation_path" const val DERIVATION_PATH_KEY = "derivation_path"
const val TRANSACTION_ID_KEY = "transaction_id" const val TRANSACTION_ID_KEY = "transaction_id"
const val PROMO_CODE_KEY = "promo_code" const val PROMO_CODE_KEY = "promo_code"
const val REF_KEY = "ref"
const val CAMPAIGN_KEY = "campaign"
const val NAME_KEY = "name" const val NAME_KEY = "name"
} }

View file

@ -56,6 +56,7 @@ interface TangemTechApi {
@Body userTokens: UserTokensResponse, @Body userTokens: UserTokensResponse,
): ApiResponse<Unit> ): ApiResponse<Unit>
// region Referral
/** Returns referral status by [walletId] */ /** Returns referral status by [walletId] */
@GET("v1/referral/{walletId}") @GET("v1/referral/{walletId}")
suspend fun getReferralStatus(@Path("walletId") walletId: String): ApiResponse<ReferralResponse> suspend fun getReferralStatus(@Path("walletId") walletId: String): ApiResponse<ReferralResponse>
@ -64,6 +65,10 @@ interface TangemTechApi {
@POST("v1/referral") @POST("v1/referral")
suspend fun startReferral(@Body startReferralBody: StartReferralBody): ApiResponse<ReferralResponse> suspend fun startReferral(@Body startReferralBody: StartReferralBody): ApiResponse<ReferralResponse>
@POST("v1/referral/bind-wallets-by-code")
suspend fun bindWalletsByReferralCode(@Body body: BindWalletsByReferralCodeBody): ApiResponse<Unit>
// endregion
@GET("v1/quotes") @GET("v1/quotes")
suspend fun getQuotes( suspend fun getQuotes(
@Query("currencyId") currencyId: String, @Query("currencyId") currencyId: String,

View file

@ -0,0 +1,11 @@
package com.tangem.datasource.api.tangemTech.models
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class BindWalletsByReferralCodeBody(
@Json(name = "walletIds") val walletIds: List<String>,
@Json(name = "referralCode") val refcode: String,
@Json(name = "utmCampaign") val campaign: String? = null,
)

View file

@ -0,0 +1,104 @@
package com.tangem.data.wallets
import androidx.datastore.preferences.core.stringPreferencesKey
import arrow.core.Option
import arrow.core.toOption
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import com.tangem.datasource.api.common.response.ApiResponse
import com.tangem.datasource.api.common.response.getOrThrow
import com.tangem.datasource.api.tangemTech.TangemTechApi
import com.tangem.datasource.api.tangemTech.models.BindWalletsByReferralCodeBody
import com.tangem.datasource.local.appsflyer.AppsFlyerConversionStore
import com.tangem.datasource.local.preferences.AppPreferencesStore
import com.tangem.datasource.local.preferences.utils.getObjectSyncOrNull
import com.tangem.datasource.local.preferences.utils.storeObject
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.domain.wallets.models.AppsFlyerConversionData
import com.tangem.domain.wallets.repository.WalletsPromoRepository
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.coroutines.runSuspendCatching
import kotlinx.coroutines.withContext
import timber.log.Timber
internal class DefaultWalletsPromoRepository(
private val appPreferencesStore: AppPreferencesStore,
private val tangemTechApi: TangemTechApi,
private val userWalletsStore: UserWalletsStore,
private val appsFlyerConversionStore: AppsFlyerConversionStore,
private val dispatchers: CoroutineDispatcherProvider,
) : WalletsPromoRepository {
override suspend fun getConversionData(): Option<AppsFlyerConversionData> {
return runSuspendCatching { appsFlyerConversionStore.get() }.getOrNull().toOption()
}
override suspend fun saveConversionData(refcode: String, campaign: String?) {
val data = AppsFlyerConversionData(refcode = refcode, campaign = campaign)
appsFlyerConversionStore.store(data)
}
override suspend fun bindRefcodeWithWallets(refcode: String, campaign: String?) = withContext(dispatchers.io) {
val walletIds = userWalletsStore.userWalletsSync.map { it.walletId.stringValue }
val result = tangemTechApi.bindWalletsByReferralCode(
body = BindWalletsByReferralCodeBody(
walletIds = walletIds,
refcode = refcode,
campaign = campaign,
),
)
val bindingData = ReferralWalletsBindingData(
refcode = refcode,
campaign = campaign,
isDone = result is ApiResponse.Success,
)
appPreferencesStore.storeObject(key = REFERRAL_WALLETS_BINDING_DATA_KEY, value = bindingData)
result.getOrThrow()
}
override suspend fun bindSavedRefcodeWithWallets(): AppsFlyerConversionData {
val bindingData = appPreferencesStore.getObjectSyncOrNull<ReferralWalletsBindingData>(
key = REFERRAL_WALLETS_BINDING_DATA_KEY,
)
if (bindingData == null) {
val exception = IllegalStateException("No saved referral wallets binding data found")
Timber.e(exception)
throw exception
}
val conversionData = AppsFlyerConversionData(
refcode = bindingData.refcode,
campaign = bindingData.campaign,
)
if (bindingData.isDone) {
Timber.i("Referral code ${bindingData.refcode} already bound with wallets")
return conversionData
}
bindRefcodeWithWallets(
refcode = bindingData.refcode,
campaign = bindingData.campaign,
)
return conversionData
}
@JsonClass(generateAdapter = true)
private data class ReferralWalletsBindingData(
@Json(name = "refcode") val refcode: String,
@Json(name = "campaign") val campaign: String?,
@Json(name = "done") val isDone: Boolean,
)
private companion object {
val REFERRAL_WALLETS_BINDING_DATA_KEY by lazy { stringPreferencesKey(name = "referralWalletsBindingData") }
}
}

View file

@ -3,6 +3,7 @@ package com.tangem.data.wallets.di
import com.squareup.moshi.Moshi import com.squareup.moshi.Moshi
import com.tangem.data.common.wallet.WalletServerBinder import com.tangem.data.common.wallet.WalletServerBinder
import com.tangem.data.wallets.DefaultWalletNamesMigrationRepository import com.tangem.data.wallets.DefaultWalletNamesMigrationRepository
import com.tangem.data.wallets.DefaultWalletsPromoRepository
import com.tangem.data.wallets.DefaultWalletsRepository import com.tangem.data.wallets.DefaultWalletsRepository
import com.tangem.data.wallets.cold.DefaultColdMapDerivationsRepository import com.tangem.data.wallets.cold.DefaultColdMapDerivationsRepository
import com.tangem.data.wallets.derivations.DefaultDerivationsRepository import com.tangem.data.wallets.derivations.DefaultDerivationsRepository
@ -21,6 +22,7 @@ import com.tangem.domain.wallets.derivations.DerivationsRepository
import com.tangem.domain.wallets.derivations.HotMapDerivationsRepository import com.tangem.domain.wallets.derivations.HotMapDerivationsRepository
import com.tangem.domain.wallets.hot.HotWalletAccessCodeAttemptsRepository import com.tangem.domain.wallets.hot.HotWalletAccessCodeAttemptsRepository
import com.tangem.domain.wallets.repository.WalletNamesMigrationRepository import com.tangem.domain.wallets.repository.WalletNamesMigrationRepository
import com.tangem.domain.wallets.repository.WalletsPromoRepository
import com.tangem.domain.wallets.repository.WalletsRepository import com.tangem.domain.wallets.repository.WalletsRepository
import com.tangem.utils.coroutines.CoroutineDispatcherProvider import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import dagger.Binds import dagger.Binds
@ -66,6 +68,24 @@ internal object WalletsDataModule {
fun provideMigrateNamesRepository(appPreferencesStore: AppPreferencesStore): WalletNamesMigrationRepository { fun provideMigrateNamesRepository(appPreferencesStore: AppPreferencesStore): WalletNamesMigrationRepository {
return DefaultWalletNamesMigrationRepository(appPreferencesStore) return DefaultWalletNamesMigrationRepository(appPreferencesStore)
} }
@Provides
@Singleton
fun provideWalletsPromoRepository(
appPreferencesStore: AppPreferencesStore,
tangemTechApi: TangemTechApi,
userWalletsStore: UserWalletsStore,
appsFlyerConversionStore: AppsFlyerConversionStore,
dispatchers: CoroutineDispatcherProvider,
): WalletsPromoRepository {
return DefaultWalletsPromoRepository(
appPreferencesStore = appPreferencesStore,
tangemTechApi = tangemTechApi,
userWalletsStore = userWalletsStore,
appsFlyerConversionStore = appsFlyerConversionStore,
dispatchers = dispatchers,
)
}
} }
@Module @Module

View file

@ -0,0 +1,15 @@
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 saveConversionData(refcode: String, campaign: String?)
suspend fun bindRefcodeWithWallets(refcode: String, campaign: String?)
suspend fun bindSavedRefcodeWithWallets(): AppsFlyerConversionData
}

View file

@ -0,0 +1,75 @@
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
import kotlinx.coroutines.sync.withLock
import javax.inject.Inject
class BindRefcodeWithWalletUseCase @Inject constructor(
private val walletsPromoRepository: WalletsPromoRepository,
) {
private val mutex = Mutex()
suspend operator fun invoke(refcode: String, campaign: String?): Either<Error, Unit> = either {
ensure(refcode.isNotBlank()) { Error.InvalidRefcode }
mutex.withLock {
checkSavedRefcode()
bindRefcode(refcode = refcode, campaign = campaign)
saveConversionData(refcode = refcode, campaign = campaign)
}
}
suspend fun retry(): Either<Error, Unit> = either {
mutex.withLock {
val conversionData = tryBindRefcodeAgain()
saveConversionData(refcode = conversionData.refcode, campaign = conversionData.campaign)
}
}
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
}
}

View file

@ -104,6 +104,7 @@ internal class WalletModel @Inject constructor(
private val singleAccountListSupplier: SingleAccountListSupplier, private val singleAccountListSupplier: SingleAccountListSupplier,
private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase, private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase,
private val feedFeatureToggle: FeedFeatureToggle, private val feedFeatureToggle: FeedFeatureToggle,
private val bindRefcodeWithWalletUseCase: BindRefcodeWithWalletUseCase,
val screenLifecycleProvider: ScreenLifecycleProvider, val screenLifecycleProvider: ScreenLifecycleProvider,
val innerWalletRouter: InnerWalletRouter, val innerWalletRouter: InnerWalletRouter,
) : Model() { ) : Model() {
@ -138,6 +139,11 @@ internal class WalletModel @Inject constructor(
enableNotificationsIfNeeded() enableNotificationsIfNeeded()
clickIntents.initialize(innerWalletRouter, modelScope) clickIntents.initialize(innerWalletRouter, modelScope)
modelScope.launch {
bindRefcodeWithWalletUseCase.retry()
.onLeft { Timber.e("Failed to bind refcode with wallets: $it") }
}
} }
fun onResume() { fun onResume() {

View file

@ -1,6 +1,7 @@
package com.tangem.feature.wallet.deeplink package com.tangem.feature.wallet.deeplink
import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.Blockchain
import com.tangem.common.routing.deeplink.DeeplinkConst
import com.tangem.common.routing.deeplink.DeeplinkConst.PROMO_CODE_KEY import com.tangem.common.routing.deeplink.DeeplinkConst.PROMO_CODE_KEY
import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.decompose.di.GlobalUiMessageSender import com.tangem.core.decompose.di.GlobalUiMessageSender
@ -19,6 +20,7 @@ import com.tangem.domain.wallets.PromoCodeActivationResult
import com.tangem.domain.wallets.PromoCodeActivationResult.* import com.tangem.domain.wallets.PromoCodeActivationResult.*
import com.tangem.domain.wallets.models.errors.ActivatePromoCodeError import com.tangem.domain.wallets.models.errors.ActivatePromoCodeError
import com.tangem.domain.wallets.usecase.ActivateBitcoinPromocodeUseCase import com.tangem.domain.wallets.usecase.ActivateBitcoinPromocodeUseCase
import com.tangem.domain.wallets.usecase.BindRefcodeWithWalletUseCase
import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase
import com.tangem.feature.wallet.deeplink.analytics.PromoActivationAnalytics import com.tangem.feature.wallet.deeplink.analytics.PromoActivationAnalytics
import com.tangem.feature.wallet.impl.R import com.tangem.feature.wallet.impl.R
@ -44,10 +46,14 @@ internal class DefaultPromoDeeplinkHandler @AssistedInject constructor(
private val multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier, private val multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier,
private val activateBitcoinPromocodeUseCase: ActivateBitcoinPromocodeUseCase, private val activateBitcoinPromocodeUseCase: ActivateBitcoinPromocodeUseCase,
private val getSelectedWalletSyncUseCase: GetSelectedWalletSyncUseCase, private val getSelectedWalletSyncUseCase: GetSelectedWalletSyncUseCase,
private val bindRefcodeWithWalletUseCase: BindRefcodeWithWalletUseCase,
private val analyticsEventsHandler: AnalyticsEventHandler, private val analyticsEventsHandler: AnalyticsEventHandler,
private val dispatchers: CoroutineDispatcherProvider, private val dispatchers: CoroutineDispatcherProvider,
) : PromoDeeplinkHandler { ) : PromoDeeplinkHandler {
private val refcode: String? = queryParams[DeeplinkConst.REF_KEY]
private val campaign: String? = queryParams[DeeplinkConst.CAMPAIGN_KEY]
init { init {
analyticsEventsHandler.send(PromoActivationAnalytics.PromoDeepLinkActivationStart()) analyticsEventsHandler.send(PromoActivationAnalytics.PromoDeepLinkActivationStart())
val promoCode = queryParams[PROMO_CODE_KEY].orEmpty() val promoCode = queryParams[PROMO_CODE_KEY].orEmpty()
@ -122,6 +128,14 @@ internal class DefaultPromoDeeplinkHandler @AssistedInject constructor(
Timber.tag(LOG_TAG).d( Timber.tag(LOG_TAG).d(
"Start activation promoCode ${promoCode.mask()} address ${bitcoinAddress.mask()}", "Start activation promoCode ${promoCode.mask()} address ${bitcoinAddress.mask()}",
) )
if (refcode != null) {
launch {
bindRefcodeWithWalletUseCase(refcode = refcode, campaign = campaign)
.onLeft { Timber.e("Failed to bind refcode with wallets: $it") }
}
}
activatePromoCode(bitcoinAddress = bitcoinAddress, promoCode = promoCode) activatePromoCode(bitcoinAddress = bitcoinAddress, promoCode = promoCode)
} else { } else {
uiMessageSender.send(GlobalLoadingMessage(false)) uiMessageSender.send(GlobalLoadingMessage(false))

View file

@ -25,6 +25,7 @@ import com.tangem.domain.wallets.PromoCodeActivationResult
import com.tangem.domain.wallets.models.GetUserWalletError import com.tangem.domain.wallets.models.GetUserWalletError
import com.tangem.domain.wallets.models.errors.ActivatePromoCodeError import com.tangem.domain.wallets.models.errors.ActivatePromoCodeError
import com.tangem.domain.wallets.usecase.ActivateBitcoinPromocodeUseCase import com.tangem.domain.wallets.usecase.ActivateBitcoinPromocodeUseCase
import com.tangem.domain.wallets.usecase.BindRefcodeWithWalletUseCase
import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase
import com.tangem.feature.wallet.deeplink.DefaultPromoDeeplinkHandler import com.tangem.feature.wallet.deeplink.DefaultPromoDeeplinkHandler
import com.tangem.feature.wallet.deeplink.analytics.PromoActivationAnalytics import com.tangem.feature.wallet.deeplink.analytics.PromoActivationAnalytics
@ -66,6 +67,9 @@ class DefaultPromoDeeplinkHandlerTest {
@MockK @MockK
private lateinit var analyticsEventHandler: AnalyticsEventHandler private lateinit var analyticsEventHandler: AnalyticsEventHandler
@MockK
private lateinit var bindRefcodeWithWalletUseCase: BindRefcodeWithWalletUseCase
private lateinit var messages: MutableList<UiMessage> private lateinit var messages: MutableList<UiMessage>
@Before @Before
@ -105,6 +109,7 @@ class DefaultPromoDeeplinkHandlerTest {
multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier, multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier,
activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase, activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase,
getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase, getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase,
bindRefcodeWithWalletUseCase = bindRefcodeWithWalletUseCase,
analyticsEventsHandler = analyticsEventHandler, analyticsEventsHandler = analyticsEventHandler,
dispatchers = dispatcherProvider, dispatchers = dispatcherProvider,
) )
@ -137,6 +142,7 @@ class DefaultPromoDeeplinkHandlerTest {
multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier, multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier,
activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase, activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase,
getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase, getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase,
bindRefcodeWithWalletUseCase = bindRefcodeWithWalletUseCase,
analyticsEventsHandler = analyticsEventHandler, analyticsEventsHandler = analyticsEventHandler,
dispatchers = TestingCoroutineDispatcherProvider(), dispatchers = TestingCoroutineDispatcherProvider(),
) )
@ -168,6 +174,7 @@ class DefaultPromoDeeplinkHandlerTest {
multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier, multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier,
activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase, activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase,
getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase, getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase,
bindRefcodeWithWalletUseCase = bindRefcodeWithWalletUseCase,
analyticsEventsHandler = analyticsEventHandler, analyticsEventsHandler = analyticsEventHandler,
dispatchers = TestingCoroutineDispatcherProvider(), dispatchers = TestingCoroutineDispatcherProvider(),
) )
@ -205,6 +212,7 @@ class DefaultPromoDeeplinkHandlerTest {
multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier, multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier,
activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase, activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase,
getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase, getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase,
bindRefcodeWithWalletUseCase = bindRefcodeWithWalletUseCase,
analyticsEventsHandler = analyticsEventHandler, analyticsEventsHandler = analyticsEventHandler,
dispatchers = dispatcherProvider, dispatchers = dispatcherProvider,
) )
@ -246,6 +254,7 @@ class DefaultPromoDeeplinkHandlerTest {
multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier, multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier,
activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase, activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase,
getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase, getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase,
bindRefcodeWithWalletUseCase = bindRefcodeWithWalletUseCase,
analyticsEventsHandler = analyticsEventHandler, analyticsEventsHandler = analyticsEventHandler,
dispatchers = dispatcherProvider, dispatchers = dispatcherProvider,
) )
@ -362,6 +371,7 @@ class DefaultPromoDeeplinkHandlerTest {
multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier, multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier,
activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase, activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase,
getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase, getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase,
bindRefcodeWithWalletUseCase = bindRefcodeWithWalletUseCase,
analyticsEventsHandler = analyticsEventHandler, analyticsEventsHandler = analyticsEventHandler,
dispatchers = dispatcherProvider, dispatchers = dispatcherProvider,
) )
@ -393,6 +403,7 @@ class DefaultPromoDeeplinkHandlerTest {
multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier, multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier,
activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase, activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase,
getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase, getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase,
bindRefcodeWithWalletUseCase = bindRefcodeWithWalletUseCase,
analyticsEventsHandler = analyticsEventHandler, analyticsEventsHandler = analyticsEventHandler,
dispatchers = dispatcherProvider, dispatchers = dispatcherProvider,
) )
@ -433,6 +444,7 @@ class DefaultPromoDeeplinkHandlerTest {
multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier, multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier,
activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase, activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase,
getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase, getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase,
bindRefcodeWithWalletUseCase = bindRefcodeWithWalletUseCase,
analyticsEventsHandler = analyticsEventHandler, analyticsEventsHandler = analyticsEventHandler,
dispatchers = dispatcherProvider, dispatchers = dispatcherProvider,
) )
@ -494,6 +506,7 @@ class DefaultPromoDeeplinkHandlerTest {
multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier, multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier,
activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase, activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase,
getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase, getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase,
bindRefcodeWithWalletUseCase = bindRefcodeWithWalletUseCase,
analyticsEventsHandler = analyticsEventHandler, analyticsEventsHandler = analyticsEventHandler,
dispatchers = dispatcherProvider, dispatchers = dispatcherProvider,
) )
@ -546,6 +559,7 @@ class DefaultPromoDeeplinkHandlerTest {
multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier, multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier,
activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase, activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase,
getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase, getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase,
bindRefcodeWithWalletUseCase = bindRefcodeWithWalletUseCase,
analyticsEventsHandler = analyticsEventHandler, analyticsEventsHandler = analyticsEventHandler,
dispatchers = dispatcherProvider, dispatchers = dispatcherProvider,
) )
@ -604,6 +618,7 @@ class DefaultPromoDeeplinkHandlerTest {
multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier, multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier,
activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase, activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase,
getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase, getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase,
bindRefcodeWithWalletUseCase = bindRefcodeWithWalletUseCase,
analyticsEventsHandler = analyticsEventHandler, analyticsEventsHandler = analyticsEventHandler,
dispatchers = dispatcherProvider, dispatchers = dispatcherProvider,
) )
@ -661,6 +676,7 @@ class DefaultPromoDeeplinkHandlerTest {
multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier, multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier,
activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase, activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase,
getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase, getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase,
bindRefcodeWithWalletUseCase = bindRefcodeWithWalletUseCase,
analyticsEventsHandler = analyticsEventHandler, analyticsEventsHandler = analyticsEventHandler,
dispatchers = dispatcherProvider, dispatchers = dispatcherProvider,
) )
@ -714,6 +730,7 @@ class DefaultPromoDeeplinkHandlerTest {
multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier, multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier,
activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase, activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase,
getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase, getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase,
bindRefcodeWithWalletUseCase = bindRefcodeWithWalletUseCase,
analyticsEventsHandler = analyticsEventHandler, analyticsEventsHandler = analyticsEventHandler,
dispatchers = dispatcherProvider, dispatchers = dispatcherProvider,
) )
@ -767,6 +784,7 @@ class DefaultPromoDeeplinkHandlerTest {
multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier, multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier,
activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase, activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase,
getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase, getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase,
bindRefcodeWithWalletUseCase = bindRefcodeWithWalletUseCase,
analyticsEventsHandler = analyticsEventHandler, analyticsEventsHandler = analyticsEventHandler,
dispatchers = dispatcherProvider, dispatchers = dispatcherProvider,
) )