Updated on 2026-08-14

This commit is contained in:
Tangem 2022-10-26 07:16:12 +03:00
commit f472f69f37
18 changed files with 165 additions and 209 deletions

View file

@ -11,21 +11,66 @@ import com.tangem.tap.common.analytics.api.ErrorEventHandler
import com.tangem.tap.common.analytics.api.ErrorEventLogger
import com.tangem.tap.common.analytics.api.SdkErrorEventHandler
import com.tangem.tap.common.analytics.api.ShopifyOrderEventHandler
import com.tangem.tap.common.analytics.events.AnalyticsEvent
import com.tangem.tap.common.extensions.filterNotNull
interface GlobalAnalyticsEventHandler : AnalyticsEventHandler,
ErrorEventHandler,
SdkErrorEventHandler,
ShopifyOrderEventHandler
ShopifyOrderEventHandler {
fun attachToAllEvents(key: String, value: String)
companion object {
fun stub(): GlobalAnalyticsEventHandler {
return object : GlobalAnalyticsEventHandler {
override fun attachToAllEvents(key: String, value: String) {}
override fun handleEvent(event: String, params: Map<String, String>) {}
override fun handleErrorEvent(error: Throwable, params: Map<String, String>) {}
override fun handleCardSdkErrorEvent(
error: TangemSdkError,
action: AnalyticsAnOld.ActionToLog,
params: Map<AnalyticsParamAnOld, String>,
card: Card?,
) {
}
override fun handleBlockchainSdkErrorEvent(
error: BlockchainError,
action: AnalyticsAnOld.ActionToLog,
params: Map<AnalyticsParamAnOld, String>,
card: Card?,
) {
}
override fun handleShopifyOrderEvent(order: Storefront.Order) {}
}
}
}
}
class GlobalAnalyticsHandler(
private val analyticsHandlers: List<AnalyticsEventHandler>,
) : GlobalAnalyticsEventHandler {
private val attachToAllEventsParams: MutableMap<String, String> = mutableMapOf()
override fun attachToAllEvents(key: String, value: String) {
attachToAllEventsParams[key] = value
}
override fun handleEvent(event: String, params: Map<String, String>) {
analyticsHandlers.forEach { it.handleEvent(event, params) }
}
override fun handleAnalyticsEvent(
event: AnalyticsEvent,
card: Card?,
blockchain: String?,
) {
analyticsHandlers.forEach { it.handleAnalyticsEvent(event, card, blockchain) }
}
override fun handleAnalyticsEvent(
event: AnalyticsEventAnOld,
params: Map<String, String>,
@ -68,6 +113,12 @@ class GlobalAnalyticsHandler(
it.handleShopifyOrderEvent(order)
}
}
override fun prepareParams(card: Card?, blockchain: String?, params: Map<String, String>): Map<String, String> {
return super.prepareParams(card, blockchain, params).toMutableMap().apply {
putAll(attachToAllEventsParams)
}
}
}
fun GlobalAnalyticsEventHandler.logWcEvent(event: AnalyticsAnOld.WcAnalyticsEvent) {

View file

@ -7,6 +7,8 @@ import com.tangem.common.core.TangemSdkError
import com.tangem.tap.common.analytics.AnalyticsAnOld
import com.tangem.tap.common.analytics.AnalyticsEventAnOld
import com.tangem.tap.common.analytics.AnalyticsParamAnOld
import com.tangem.tap.common.analytics.events.AnalyticsEvent
import com.tangem.tap.common.analytics.events.AnalyticsParam
import com.tangem.tap.common.extensions.filterNotNull
/**
@ -18,22 +20,40 @@ interface AnalyticsEventHandler {
params: Map<String, String> = emptyMap(),
)
fun handleAnalyticsEvent(
event: AnalyticsEvent,
card: Card? = null,
blockchain: String? = null,
) {
handleEvent(
event = prepareEventString(event.category, event.event),
params = prepareParams(card, blockchain, event.params),
)
}
@Deprecated("Migrate to AnalyticsEvent")
fun handleAnalyticsEvent(
event: AnalyticsEventAnOld,
params: Map<String, String> = emptyMap(),
card: Card? = null,
blockchain: String? = null,
)
) {
handleEvent(event.event, prepareParams(card, blockchain, params))
}
fun prepareParams(
card: Card?,
card: Card? = null,
blockchain: String? = null,
params: Map<String, String> = emptyMap(),
): Map<String, String> = mapOf(
AnalyticsParamAnOld.FIRMWARE.param to card?.firmwareVersion?.stringValue,
AnalyticsParamAnOld.BATCH_ID.param to card?.batchId,
AnalyticsParamAnOld.BLOCKCHAIN.param to blockchain,
AnalyticsParam.Firmware to card?.firmwareVersion?.stringValue,
AnalyticsParam.BatchId to card?.batchId,
AnalyticsParam.Blockchain to blockchain,
).filterNotNull() + params
fun prepareEventString(category: String, event: String): String {
return "[$category] $event"
}
}
interface ErrorEventHandler {

View file

@ -49,4 +49,10 @@ sealed class AnalyticsParam {
object LinkedIn : SocialNetwork("LinkedIn")
object GitHub : SocialNetwork("GitHub")
}
companion object Key {
const val Blockchain = "blockchain"
const val BatchId = "batch_id"
const val Firmware = "firmware"
}
}

View file

@ -64,4 +64,13 @@ sealed class Onboarding(
class SetupStarted : Twins("Twin Setup Started")
class SetupFinished : Twins("Twin Setup Finished")
}
class PinCodeSet: Onboarding("Onboarding", "PIN code set")
class ButtonConnect: Onboarding("Onboarding", "Button - Connect")
class KYCStarted: Onboarding("Onboarding", "KYC started")
class KYCInProgress: Onboarding("Onboarding", "KYC in progress")
class KYCRejected: Onboarding("Onboarding", "KYC rejected")
class ClaimScreenOpened: Onboarding("Onboarding", "Claim screen opened")
class ButtonClaim: Onboarding("Onboarding", "Button - Claim")
class ClaimWasSuccessfully: Onboarding("Onboarding", "Claim was successfully")
}

View file

@ -1,7 +1,5 @@
package com.tangem.tap.common.analytics.handlers.amplitude
import com.tangem.common.card.Card
import com.tangem.tap.common.analytics.AnalyticsEventAnOld
import com.tangem.tap.common.analytics.api.AnalyticsEventHandler
class AmplitudeAnalyticsHandler(
@ -11,13 +9,4 @@ class AmplitudeAnalyticsHandler(
override fun handleEvent(event: String, params: Map<String, String>) {
client.logEvent(event, params)
}
override fun handleAnalyticsEvent(
event: AnalyticsEventAnOld,
params: Map<String, String>,
card: Card?,
blockchain: String?,
) {
handleEvent(event.event, prepareParams(card, blockchain, params))
}
}

View file

@ -4,8 +4,6 @@ import com.appsflyer.AFInAppEventParameterName
import com.appsflyer.AFInAppEventType
import com.shopify.buy3.Storefront
import com.tangem.common.Converter
import com.tangem.common.card.Card
import com.tangem.tap.common.analytics.AnalyticsEventAnOld
import com.tangem.tap.common.analytics.api.AnalyticsEventHandler
import com.tangem.tap.common.analytics.api.ShopifyOrderEventHandler
@ -17,15 +15,6 @@ class AppsFlyerAnalyticsHandler(
client.logEvent(event, params)
}
override fun handleAnalyticsEvent(
event: AnalyticsEventAnOld,
params: Map<String, String>,
card: Card?,
blockchain: String?,
) {
handleEvent(event.event, prepareParams(card, blockchain, params))
}
override fun handleShopifyOrderEvent(order: Storefront.Order) {
handleEvent(ORDER_EVENT, OrderToParamsConverter().convert(order))
}

View file

@ -7,7 +7,6 @@ import com.tangem.common.Converter
import com.tangem.common.card.Card
import com.tangem.common.core.TangemSdkError
import com.tangem.tap.common.analytics.AnalyticsAnOld
import com.tangem.tap.common.analytics.AnalyticsEventAnOld
import com.tangem.tap.common.analytics.AnalyticsParamAnOld
import com.tangem.tap.common.analytics.api.AnalyticsEventHandler
import com.tangem.tap.common.analytics.api.ErrorEventHandler
@ -24,15 +23,6 @@ class FirebaseAnalyticsHandler(
client.logEvent(event, params)
}
override fun handleAnalyticsEvent(
event: AnalyticsEventAnOld,
params: Map<String, String>,
card: Card?,
blockchain: String?,
) {
handleEvent(event.name, prepareParams(card, blockchain, params))
}
override fun handleErrorEvent(error: Throwable, params: Map<String, String>) {
client.logErrorEvent(error, params)
}

View file

@ -44,8 +44,13 @@ suspend fun WalletManager.safeUpdate(): Result<Wallet> = try {
if (exception is BlockchainSdkError.AccountNotFound && amountToCreateAccount != null) {
Result.Failure(TapError.WalletManager.NoAccountError(amountToCreateAccount.toString()))
} else {
val message = exception.localizedMessage ?: "An error has occurred. Try later"
Result.Failure(TapError.WalletManager.InternalError(message))
when (exception) {
is BlockchainSdkError -> Result.Failure(exception)
else -> {
val message = exception.cause?.localizedMessage ?: "Unknown error"
Result.Failure(TapError.WalletManager.InternalError(message))
}
}
}
}
}
@ -72,7 +77,7 @@ fun WalletManager?.getAddressData(): AddressData? {
else addressDataList[0]
}
fun<T> WalletManager.Companion.stub(): T {
fun <T> WalletManager.Companion.stub(): T {
val wallet = Wallet(Blockchain.Unknown, setOf(), Wallet.PublicKey(byteArrayOf(), null, null), setOf())
return object : WalletManager(wallet) {
override val currentHost: String = ""

View file

@ -27,7 +27,7 @@ data class GlobalState(
val dialog: StateDialog? = null,
val exchangeManager: CurrencyExchangeManager = CurrencyExchangeManager.dummy(),
val resources: AndroidResources = AndroidResources(),
val analyticsHandler: GlobalAnalyticsEventHandler? = null,
val analyticsHandler: GlobalAnalyticsEventHandler = GlobalAnalyticsEventHandler.stub(),
val userCountryCode: String? = null,
) : StateType

View file

@ -9,6 +9,7 @@ import com.tangem.tap.DELAY_SDK_DIALOG_CLOSE
import com.tangem.tap.common.analytics.AnalyticsEventAnOld
import com.tangem.tap.common.analytics.AnalyticsParamAnOld
import com.tangem.tap.common.analytics.GetCardSourceParamsAnOld
import com.tangem.tap.common.analytics.events.AnalyticsParam
import com.tangem.tap.common.entities.IndeterminateProgressButton
import com.tangem.tap.common.extensions.dispatchDialogShow
import com.tangem.tap.common.extensions.dispatchOpenUrl
@ -121,6 +122,8 @@ private fun onScanSuccess(scanResponse: ScanResponse) {
val tapWalletManager = globalState.tapWalletManager
tapWalletManager.updateConfigManager(scanResponse)
globalState.analyticsHandler.attachToAllEvents(AnalyticsParam.BatchId, scanResponse.card.batchId)
store.dispatch(TwinCardsAction.IfTwinsPrepareState(scanResponse))
if (scanResponse.isSaltPay()) {

View file

@ -19,11 +19,7 @@ class OnboardingSaltPayHelper {
manager: SaltPayActivationManager,
): Result<Boolean> {
return try {
val status = manager.updateActivationStatus(
amountToClaim = null,
step = SaltPayActivationStep.None,
).successOr { return it }
val status = manager.updateActivationStatus(null).successOr { return it }
val isRegistrationCase = status.step != SaltPayActivationStep.Finished
val isBackupCase = scanResponse.card.backupStatus?.isActive == false
Result.Success(isRegistrationCase || isBackupCase)

View file

@ -4,6 +4,7 @@ import android.net.Uri
import com.tangem.blockchain.blockchains.ethereum.SignedEthereumTransaction
import com.tangem.blockchain.common.Amount
import com.tangem.blockchain.common.AmountType
import com.tangem.blockchain.common.BlockchainSdkError
import com.tangem.blockchain.common.TransactionSigner
import com.tangem.blockchain.extensions.successOr
import com.tangem.common.extensions.guard
@ -21,7 +22,6 @@ import com.tangem.tap.common.extensions.safeUpdate
import com.tangem.tap.domain.getFirstToken
import com.tangem.tap.domain.tokens.UserWalletId
import com.tangem.tap.features.onboarding.products.wallet.saltPay.message.SaltPayActivationError
import com.tangem.tap.persistence.SaltPayActivationStorage
import java.math.BigDecimal
/**
@ -34,7 +34,6 @@ class SaltPayActivationManager(
private val kycProvider: KYCProvider,
private val paymentologyService: PaymentologyApiService,
private val gnosisRegistrator: GnosisRegistrator,
private val registrationStorage: SaltPayActivationStorage,
) {
val kycUrlProvider = KYCUrlProvider(walletPublicKey, kycProvider)
@ -43,10 +42,6 @@ class SaltPayActivationManager(
private val spendLimitValue: BigDecimal = BigDecimal("100")
fun transactionIsSent(): Boolean {
return registrationStorage.data.transactionsSent
}
suspend fun checkHasGas(): Result<Unit> {
return when (val hasGasResult = gnosisRegistrator.checkHasGas()) {
is com.tangem.blockchain.extensions.Result.Success -> if (hasGasResult.data) {
@ -54,7 +49,7 @@ class SaltPayActivationManager(
} else {
Result.Failure(SaltPayActivationError.NoGas)
}
is com.tangem.blockchain.extensions.Result.Failure -> Result.Failure(SaltPayActivationError.NoGas)
is com.tangem.blockchain.extensions.Result.Failure -> Result.Failure(hasGasResult.error as BlockchainSdkError)
}
}
@ -103,13 +98,7 @@ class SaltPayActivationManager(
pin = pinCode,
)
val result = paymentologyService.registerWallet(request)
registrationStorage.data = registrationStorage.data.copy(
transactionsSent = result is Result.Success,
)
return result
return paymentologyService.registerWallet(request)
}
suspend fun getAmountToClaim(): Result<Amount> {
@ -166,7 +155,6 @@ class SaltPayActivationManager(
kycProvider = SaltPayConfig.stub().kycProvider,
paymentologyService = PaymentologyApiService.stub(),
gnosisRegistrator = GnosisRegistrator.stub(),
registrationStorage = SaltPayActivationStorage.stub(),
cardId = "",
cardPublicKey = byteArrayOf(),
walletPublicKey = byteArrayOf(),

View file

@ -1,5 +1,6 @@
package com.tangem.tap.features.onboarding.products.wallet.saltPay
import com.tangem.blockchain.common.BlockchainSdkError
import com.tangem.common.core.TangemSdkError
import com.tangem.tap.common.extensions.dispatchDialogShow
import com.tangem.tap.common.redux.AppDialog
@ -21,7 +22,6 @@ class SaltPayExceptionHandler {
}
store.dispatchDialogShow(dialog)
}
is TangemSdkError -> {
when (throwable) {
is TangemSdkError.NetworkError -> {
@ -33,8 +33,11 @@ class SaltPayExceptionHandler {
}
}
}
is BlockchainSdkError -> {
store.dispatchDialogShow(AppDialog.SimpleOkErrorDialog(throwable.customMessage))
}
else -> {
val message = throwable.message ?: "SaltPay unknown error"
val message = throwable.localizedMessage ?: "SaltPay unknown error"
store.dispatchDialogShow(AppDialog.SimpleOkErrorDialog(message))
}
}

View file

@ -10,7 +10,10 @@ import com.tangem.domain.common.extensions.successOr
import com.tangem.domain.common.extensions.withMainContext
import com.tangem.network.api.paymentology.KYCStatus
import com.tangem.network.api.paymentology.RegistrationResponse
import com.tangem.tap.common.analytics.GlobalAnalyticsEventHandler
import com.tangem.tap.common.analytics.events.Onboarding
import com.tangem.tap.common.extensions.dispatchOnMain
import com.tangem.tap.common.extensions.isPositive
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.common.redux.global.GlobalAction
import com.tangem.tap.domain.TangemSigner
@ -56,6 +59,7 @@ private fun handleOnboardingSaltPayAction(anyAction: Action, appState: () -> App
fun getAppState(): AppState = appState()!!
fun getOnboardingWalletState(): OnboardingWalletState = getAppState().onboardingWalletState
fun getState(): OnboardingSaltPayState = getOnboardingWalletState().onboardingSaltPayState!!
val analyticsHandler = getAppState().globalState.analyticsHandler
when (action) {
is OnboardingSaltPayAction.Update -> {
@ -63,21 +67,18 @@ private fun handleOnboardingSaltPayAction(anyAction: Action, appState: () -> App
val state = getState()
scope.launch {
val updateResult = state.saltPayManager.updateActivationStatus(
amountToClaim = state.amountToClaim,
step = state.step,
).successOr {
val updateResult = state.saltPayManager.updateActivationStatus(state.amountToClaim).successOr {
onException(it.error)
return@launch
}
handleInProgress = false
withMainContext {
store.dispatch(OnboardingSaltPayAction.SetStep(updateResult.step))
}
dispatchOnMain(OnboardingSaltPayAction.SetStep(updateResult.step))
}
}
is OnboardingSaltPayAction.RegisterCard -> {
analyticsHandler.handleAnalyticsEvent(Onboarding.ButtonConnect())
handleInProgress = true
val state = getState()
@ -126,10 +127,8 @@ private fun handleOnboardingSaltPayAction(anyAction: Action, appState: () -> App
return@launch
}
withMainContext {
handleInProgress = false
store.dispatch(OnboardingSaltPayAction.SetStep(SaltPayActivationStep.KycIntro))
}
handleInProgress = false
dispatchOnMain(OnboardingSaltPayAction.SetStep(SaltPayActivationStep.KycIntro))
}
}
is OnboardingSaltPayAction.OpenUtorgKYC -> {
@ -140,20 +139,24 @@ private fun handleOnboardingSaltPayAction(anyAction: Action, appState: () -> App
}
is OnboardingSaltPayAction.RegisterKYC -> {
val state = getState()
store.dispatch(OnboardingSaltPayAction.SetStep(SaltPayActivationStep.KycWaiting))
handleInProgress = true
scope.launch {
registerKYCIfNeeded(state.saltPayManager, state.step).successOr {
Timber.d("saltPayManager.registerKYC()")
state.saltPayManager.registerKYC().successOr {
onException(it.error)
return@launch
}
handleInProgress = false
withMainContext { store.dispatch(OnboardingSaltPayAction.Update) }
dispatchOnMain(OnboardingSaltPayAction.Update)
}
}
is OnboardingSaltPayAction.TrySetPin -> {
try {
assertPinValid(action.pin, getState().pinLength)
analyticsHandler.handleAnalyticsEvent(Onboarding.PinCodeSet())
store.dispatch(OnboardingSaltPayAction.SetPin(action.pin))
store.dispatch(OnboardingSaltPayAction.SetStep(SaltPayActivationStep.CardRegistration))
} catch (error: SaltPayActivationError) {
@ -161,6 +164,7 @@ private fun handleOnboardingSaltPayAction(anyAction: Action, appState: () -> App
}
}
is OnboardingSaltPayAction.Claim -> {
analyticsHandler.handleAnalyticsEvent(Onboarding.ButtonClaim())
val state = getState()
handleInProgress = true
@ -191,7 +195,7 @@ private fun handleOnboardingSaltPayAction(anyAction: Action, appState: () -> App
onException(it.error)
return@launch
}
analyticsHandler.handleAnalyticsEvent(Onboarding.ClaimWasSuccessfully())
dispatchOnMain(OnboardingSaltPayAction.SetStep(SaltPayActivationStep.ClaimInProgress))
dispatchOnMain(OnboardingSaltPayAction.RefreshClaim)
}
@ -202,47 +206,61 @@ private fun handleOnboardingSaltPayAction(anyAction: Action, appState: () -> App
val state = getState()
scope.launch {
val balance = state.saltPayManager.getTokenAmount().successOr {
val tokenAmountValue = state.saltPayManager.getTokenAmount().successOr {
SaltPayExceptionHandler.handle(it.error)
handleClaimRefreshInProgress = false
return@launch
}
handleInProgress = false
handleClaimRefreshInProgress = false
dispatchOnMain(OnboardingSaltPayAction.SetTokenBalance(balance))
dispatchOnMain(OnboardingSaltPayAction.SetStep(SaltPayActivationStep.Finished))
if (tokenAmountValue.isPositive()) {
handleInProgress = false
handleClaimRefreshInProgress = false
dispatchOnMain(OnboardingSaltPayAction.SetTokenBalance(tokenAmountValue))
dispatchOnMain(OnboardingSaltPayAction.SetStep(SaltPayActivationStep.Finished))
} else {
handleClaimRefreshInProgress = false
}
}
}
is OnboardingSaltPayAction.SetStep -> handleAnalytics(analyticsHandler, action.newStep)
else -> {
/* do nothing, only reduce */
}
}
}
fun handleAnalytics(analyticsHandler: GlobalAnalyticsEventHandler, step: SaltPayActivationStep?) {
when (step) {
SaltPayActivationStep.None -> {}
SaltPayActivationStep.NoGas -> {}
SaltPayActivationStep.NeedPin -> {}
SaltPayActivationStep.CardRegistration -> {}
SaltPayActivationStep.KycIntro -> {}
SaltPayActivationStep.KycStart -> analyticsHandler.handleAnalyticsEvent(Onboarding.KYCStarted())
SaltPayActivationStep.KycWaiting -> analyticsHandler.handleAnalyticsEvent(Onboarding.KYCInProgress())
SaltPayActivationStep.KycReject -> analyticsHandler.handleAnalyticsEvent(Onboarding.KYCRejected())
SaltPayActivationStep.Claim -> analyticsHandler.handleAnalyticsEvent(Onboarding.ClaimScreenOpened())
SaltPayActivationStep.ClaimInProgress -> {}
SaltPayActivationStep.Finished -> {}
null -> {}
}
}
data class UpdateResult(
val step: SaltPayActivationStep = SaltPayActivationStep.None,
val amountToClaim: Amount? = null,
)
suspend fun SaltPayActivationManager.updateActivationStatus(
amountToClaim: Amount?,
step: SaltPayActivationStep,
): Result<UpdateResult> {
suspend fun SaltPayActivationManager.updateActivationStatus(amountToClaim: Amount?): Result<UpdateResult> {
Timber.d("updateSaltPayStatus")
var updateResult = UpdateResult()
checkGasIfNeeded(this, step).successOr {
return Result.Failure(it.error)
}
registerKYCIfNeeded(this, step).successOr {
return Result.Failure(it.error)
}
val saltPayStep = checkRegistration(this).successOr {
return Result.Failure(it.error)
}
checkGasIfNeeded(this, saltPayStep).successOr {
return Result.Failure(it.error)
}
val fetchedAmountToClaim = getAmountToClaimIfNeeded(this, amountToClaim)
@ -317,10 +335,7 @@ private suspend fun checkGasIfNeeded(
step: SaltPayActivationStep,
): Result<Unit> {
Timber.d("checkGasIfNeeded: for step: %s", step)
if (step == SaltPayActivationStep.KycStart ||
step == SaltPayActivationStep.KycWaiting ||
step == SaltPayActivationStep.Finished
) {
if (step.ordinal >= SaltPayActivationStep.KycIntro.ordinal) {
Timber.d("checkGasIfNeeded: no need to check for step: %s", step)
return Result.Success(Unit)
}
@ -333,25 +348,6 @@ private suspend fun checkGasIfNeeded(
return result
}
private suspend fun registerKYCIfNeeded(
saltPayManager: SaltPayActivationManager,
step: SaltPayActivationStep,
): Result<Unit> {
Timber.d("registerKYCIfNeeded: step: %s", step)
if (step != SaltPayActivationStep.KycStart) {
Timber.d("registerKYCIfNeeded: return Success, because step != KycStart")
return Result.Success(Unit)
}
withMainContext {
Timber.d("registerKYCIfNeeded: set new step: KycWaiting")
store.dispatch(OnboardingSaltPayAction.SetStep(SaltPayActivationStep.KycWaiting))
}
Timber.d("saltPayManager.registerKYC()")
return saltPayManager.registerKYC()
}
private suspend fun checkRegistration(
saltPayManager: SaltPayActivationManager,
): Result<SaltPayActivationStep> {
@ -386,7 +382,7 @@ fun RegistrationResponse.Item.toSaltPayStep(): SaltPayActivationStep {
kycStatus != null -> {
when (kycStatus) {
KYCStatus.NOT_STARTED, KYCStatus.STARTED -> SaltPayActivationStep.KycStart
KYCStatus.NOT_STARTED, KYCStatus.STARTED -> SaltPayActivationStep.KycIntro
KYCStatus.WAITING_FOR_APPROVAL -> SaltPayActivationStep.KycWaiting
KYCStatus.CORRECTION_REQUESTED, KYCStatus.REJECTED -> SaltPayActivationStep.KycReject
KYCStatus.APPROVED -> SaltPayActivationStep.Claim

View file

@ -17,8 +17,6 @@ import com.tangem.tap.features.onboarding.products.wallet.saltPay.KYCProvider
import com.tangem.tap.features.onboarding.products.wallet.saltPay.SaltPayActivationManager
import com.tangem.tap.features.onboarding.products.wallet.saltPay.SaltPayConfig
import com.tangem.tap.features.wallet.redux.ProgressState
import com.tangem.tap.persistence.SaltPayActivationStorage
import com.tangem.tap.preferencesStorage
import com.tangem.tap.store
import java.math.BigDecimal
@ -60,7 +58,6 @@ data class OnboardingSaltPayState(
scanResponse = scanResponse,
gnosisRegistrator = gnosisRegistrator,
paymentologyService = store.state.domainNetworks.paymentologyService,
registrationStorage = preferencesStorage.saltPayActivationStorage,
kycProvider = saltPayConfig.kycProvider,
)
test(scanResponse, gnosisRegistrator)
@ -83,7 +80,6 @@ data class OnboardingSaltPayState(
scanResponse: ScanResponse,
gnosisRegistrator: GnosisRegistrator,
paymentologyService: PaymentologyApiService,
registrationStorage: SaltPayActivationStorage,
kycProvider: KYCProvider,
): SaltPayActivationManager {
if (!scanResponse.isSaltPay()) {
@ -100,7 +96,6 @@ data class OnboardingSaltPayState(
kycProvider = kycProvider,
paymentologyService = paymentologyService,
gnosisRegistrator = gnosisRegistrator,
registrationStorage = registrationStorage,
)
}

View file

@ -240,7 +240,7 @@ internal class OnboardingSaltPayView(
btnOpenSupportChat.hide()
btnKycAction.text = getString(R.string.onboarding_button_kyc_start)
btnKycAction.setOnClickListener {
store.dispatch(OnboardingSaltPayAction.Update)
store.dispatch(OnboardingSaltPayAction.SetStep(SaltPayActivationStep.KycStart))
}
progressButton = SaltPayProgressButton(root)
}

View file

@ -15,7 +15,6 @@ class PreferencesStorage(applicationContext: Application) {
val appRatingLaunchObserver: AppRatingLaunchObserver
val usedCardsPrefStorage: UsedCardsPrefStorage
val fiatCurrenciesPrefStorage: FiatCurrenciesPrefStorage
val saltPayActivationStorage: SaltPayActivationStorage
val disclaimerPrefStorage: DisclaimerPrefStorage
init {
@ -25,7 +24,6 @@ class PreferencesStorage(applicationContext: Application) {
usedCardsPrefStorage.migrate()
fiatCurrenciesPrefStorage = FiatCurrenciesPrefStorage(preferences, MoshiJsonConverter.INSTANCE)
fiatCurrenciesPrefStorage.migrate()
saltPayActivationStorage = SaltPayActivationPrefStorage(applicationContext, MoshiJsonConverter.INSTANCE)
disclaimerPrefStorage = DisclaimerPrefStorage(preferences)
}

View file

@ -1,82 +0,0 @@
package com.tangem.tap.persistence
import android.content.Context
import androidx.core.content.edit
import at.favre.lib.armadillo.ArmadilloSharedPreferences
import com.tangem.common.json.MoshiJsonConverter
import com.tangem.common.services.secure.SecureStorage
import com.tangem.tangem_sdk_new.storage.createEncryptedSharedPreferences
/**
[REDACTED_AUTHOR]
*/
interface SaltPayActivationStorage {
var data: SaltPayActivationData
fun reset()
companion object {
fun stub(): SaltPayActivationStorage = object : SaltPayActivationStorage {
override var data: SaltPayActivationData = SaltPayActivationData()
override fun reset() {}
}
}
}
data class SaltPayActivationData(
val transactionsSent: Boolean = false,
)
class SaltPayActivationPrefStorage(
context: Context,
private val converter: MoshiJsonConverter,
) : SaltPayActivationStorage {
private val storage: ArmadilloSharedPreferences = SecureStorage.createEncryptedSharedPreferences(
context = context,
storageName = "saltpay",
)
private var isFetching: Boolean = false
init {
fetch()
}
override var data: SaltPayActivationData = SaltPayActivationData()
set(value) {
field = value
if (!isFetching) save()
}
override fun reset() {
storage.edit(true) {
this.remove(REGISTRATION_DATA_KEY)
data = SaltPayActivationData()
}
}
private fun save() {
storage.edit(true) {
putString(REGISTRATION_DATA_KEY, converter.toJson(data))
}
}
private fun fetch(): SaltPayActivationData {
isFetching = true
val jsonData = storage.getString(REGISTRATION_DATA_KEY, null)
data = if (jsonData == null) {
SaltPayActivationData()
} else {
converter.fromJson<SaltPayActivationData>(jsonData) ?: SaltPayActivationData()
}
isFetching = false
return data
}
companion object {
private const val REGISTRATION_DATA_KEY = "saltpay_registration_data"
}
}