Updated on 2026-08-14
This commit is contained in:
commit
f472f69f37
18 changed files with 165 additions and 209 deletions
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
@ -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")
|
||||
}
|
||||
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
|
@ -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))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 = ""
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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()) {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue