Updated on 2026-08-14
This commit is contained in:
parent
8e6eca1b4c
commit
e20956359c
9 changed files with 169 additions and 28 deletions
|
|
@ -7,6 +7,7 @@ import com.tangem.blockchainsdk.utils.ExcludedBlockchains
|
||||||
import com.tangem.common.routing.AppRouter
|
import com.tangem.common.routing.AppRouter
|
||||||
import com.tangem.core.abtests.manager.ABTestsManager
|
import com.tangem.core.abtests.manager.ABTestsManager
|
||||||
import com.tangem.core.analytics.filter.OneTimeEventFilter
|
import com.tangem.core.analytics.filter.OneTimeEventFilter
|
||||||
|
import com.tangem.core.analytics.paramsinterceptor.SendTransactionSignerInfoInterceptor
|
||||||
import com.tangem.core.analytics.utils.TrackingContextProxy
|
import com.tangem.core.analytics.utils.TrackingContextProxy
|
||||||
import com.tangem.core.configtoggle.blockchain.ExcludedBlockchainsManager
|
import com.tangem.core.configtoggle.blockchain.ExcludedBlockchainsManager
|
||||||
import com.tangem.core.configtoggle.feature.FeatureTogglesManager
|
import com.tangem.core.configtoggle.feature.FeatureTogglesManager
|
||||||
|
|
@ -151,4 +152,6 @@ interface ApplicationEntryPoint {
|
||||||
fun getAppsFlyerClientFactory(): AppsFlyerClient.Factory
|
fun getAppsFlyerClientFactory(): AppsFlyerClient.Factory
|
||||||
|
|
||||||
fun getScanFailsRequester(): ScanFailsRequester
|
fun getScanFailsRequester(): ScanFailsRequester
|
||||||
|
|
||||||
|
fun getSendTransactionSignerInfoInterceptor(): SendTransactionSignerInfoInterceptor
|
||||||
}
|
}
|
||||||
|
|
@ -18,13 +18,8 @@ import com.tangem.blockchainsdk.utils.ExcludedBlockchains
|
||||||
import com.tangem.common.routing.AppRouter
|
import com.tangem.common.routing.AppRouter
|
||||||
import com.tangem.core.abtests.manager.ABTestsManager
|
import com.tangem.core.abtests.manager.ABTestsManager
|
||||||
import com.tangem.core.analytics.Analytics
|
import com.tangem.core.analytics.Analytics
|
||||||
import com.tangem.core.analytics.api.ParamsInterceptor
|
|
||||||
import com.tangem.core.analytics.filter.AppsFlyerEventFilter
|
import com.tangem.core.analytics.filter.AppsFlyerEventFilter
|
||||||
import com.tangem.core.analytics.filter.OneTimeEventFilter
|
import com.tangem.core.analytics.filter.OneTimeEventFilter
|
||||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
|
||||||
import com.tangem.core.analytics.models.AnalyticsParam
|
|
||||||
import com.tangem.core.analytics.models.Basic
|
|
||||||
import com.tangem.core.analytics.models.Basic.TransactionSent.WalletForm
|
|
||||||
import com.tangem.core.configtoggle.blockchain.ExcludedBlockchainsManager
|
import com.tangem.core.configtoggle.blockchain.ExcludedBlockchainsManager
|
||||||
import com.tangem.core.configtoggle.feature.FeatureTogglesManager
|
import com.tangem.core.configtoggle.feature.FeatureTogglesManager
|
||||||
import com.tangem.core.decompose.ui.UiMessageSender
|
import com.tangem.core.decompose.ui.UiMessageSender
|
||||||
|
|
@ -238,6 +233,9 @@ open class TangemApplication : Application(), ImageLoaderFactory, Configuration.
|
||||||
private val scanFailsRequester
|
private val scanFailsRequester
|
||||||
get() = entryPoint.getScanFailsRequester()
|
get() = entryPoint.getScanFailsRequester()
|
||||||
|
|
||||||
|
private val sendTransactionSignerInfoInterceptor
|
||||||
|
get() = entryPoint.getSendTransactionSignerInfoInterceptor()
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
private val appScope = MainScope()
|
private val appScope = MainScope()
|
||||||
|
|
@ -424,23 +422,7 @@ open class TangemApplication : Application(), ImageLoaderFactory, Configuration.
|
||||||
jsonConverter = MoshiConverter.sdkMoshiConverter,
|
jsonConverter = MoshiConverter.sdkMoshiConverter,
|
||||||
)
|
)
|
||||||
|
|
||||||
Analytics.addParamsInterceptor(
|
Analytics.addParamsInterceptor(interceptor = sendTransactionSignerInfoInterceptor)
|
||||||
interceptor = object : ParamsInterceptor {
|
|
||||||
override fun id(): String = "SendTransactionSignerInfoInterceptor"
|
|
||||||
|
|
||||||
override fun canBeAppliedTo(event: AnalyticsEvent): Boolean = event is Basic.TransactionSent
|
|
||||||
|
|
||||||
override fun intercept(params: MutableMap<String, String>) {
|
|
||||||
val isLastSignWithRing = store.state.globalState.isLastSignWithRing
|
|
||||||
|
|
||||||
params[AnalyticsParam.WALLET_FORM] = if (isLastSignWithRing) {
|
|
||||||
WalletForm.Ring.name
|
|
||||||
} else {
|
|
||||||
WalletForm.Card.name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
factory.build(Analytics, buildData)
|
factory.build(Analytics, buildData)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,15 @@ package com.tangem.tap.common.libs.blockchainsdk
|
||||||
import com.tangem.Message
|
import com.tangem.Message
|
||||||
import com.tangem.TangemSdk
|
import com.tangem.TangemSdk
|
||||||
import com.tangem.blockchain.common.TransactionSigner
|
import com.tangem.blockchain.common.TransactionSigner
|
||||||
|
import com.tangem.core.analytics.models.Basic.TransactionSent.WalletForm
|
||||||
|
import com.tangem.core.analytics.store.LastSignedWalletFormStore
|
||||||
import com.tangem.data.card.TransactionSignerFactory
|
import com.tangem.data.card.TransactionSignerFactory
|
||||||
import com.tangem.domain.card.models.TwinKey
|
import com.tangem.domain.card.models.TwinKey
|
||||||
import com.tangem.tap.common.redux.global.GlobalAction
|
|
||||||
import com.tangem.tap.domain.TangemSigner
|
import com.tangem.tap.domain.TangemSigner
|
||||||
import com.tangem.tap.store
|
|
||||||
|
|
||||||
internal class DefaultTransactionSignerFactory : TransactionSignerFactory {
|
internal class DefaultTransactionSignerFactory(
|
||||||
|
private val lastSignedWalletFormStore: LastSignedWalletFormStore,
|
||||||
|
) : TransactionSignerFactory {
|
||||||
|
|
||||||
override fun createTransactionSigner(cardId: String?, sdk: TangemSdk, twinKey: TwinKey?): TransactionSigner {
|
override fun createTransactionSigner(cardId: String?, sdk: TangemSdk, twinKey: TwinKey?): TransactionSigner {
|
||||||
return TangemSigner(
|
return TangemSigner(
|
||||||
|
|
@ -18,7 +20,9 @@ internal class DefaultTransactionSignerFactory : TransactionSignerFactory {
|
||||||
initialMessage = Message(),
|
initialMessage = Message(),
|
||||||
twinKey = twinKey,
|
twinKey = twinKey,
|
||||||
) { signResponse ->
|
) { signResponse ->
|
||||||
store.dispatch(action = GlobalAction.IsSignWithRing(signResponse.isRing))
|
lastSignedWalletFormStore.update(
|
||||||
|
if (signResponse.isRing) WalletForm.Ring else WalletForm.Card,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package com.tangem.tap.di.libs.blockchainsdk
|
package com.tangem.tap.di.libs.blockchainsdk
|
||||||
|
|
||||||
|
import com.tangem.core.analytics.store.LastSignedWalletFormStore
|
||||||
import com.tangem.data.card.TransactionSignerFactory
|
import com.tangem.data.card.TransactionSignerFactory
|
||||||
import com.tangem.tap.common.libs.blockchainsdk.DefaultTransactionSignerFactory
|
import com.tangem.tap.common.libs.blockchainsdk.DefaultTransactionSignerFactory
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
|
|
@ -17,7 +18,9 @@ internal class TransactionSignerFactoryModule {
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
fun provideTransactionSignerFactory(): TransactionSignerFactory {
|
fun provideTransactionSignerFactory(
|
||||||
return DefaultTransactionSignerFactory()
|
lastSignedWalletFormStore: LastSignedWalletFormStore,
|
||||||
|
): TransactionSignerFactory {
|
||||||
|
return DefaultTransactionSignerFactory(lastSignedWalletFormStore)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4,6 +4,10 @@ plugins {
|
||||||
id("configuration")
|
id("configuration")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tasks.withType<Test>().configureEach {
|
||||||
|
useJUnitPlatform()
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|
||||||
/** DI */
|
/** DI */
|
||||||
|
|
@ -25,4 +29,8 @@ dependencies {
|
||||||
|
|
||||||
/** For calculating user id hash */
|
/** For calculating user id hash */
|
||||||
implementation(tangemDeps.card.core)
|
implementation(tangemDeps.card.core)
|
||||||
|
|
||||||
|
/** Tests */
|
||||||
|
testImplementation(projects.test.core)
|
||||||
|
testRuntimeOnly(deps.test.junit5.engine)
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.tangem.core.analytics.di
|
||||||
|
|
||||||
|
import com.tangem.core.analytics.paramsinterceptor.SendTransactionSignerInfoInterceptor
|
||||||
|
import com.tangem.core.analytics.store.LastSignedWalletFormStore
|
||||||
|
import dagger.Binds
|
||||||
|
import dagger.Module
|
||||||
|
import dagger.hilt.InstallIn
|
||||||
|
import dagger.hilt.components.SingletonComponent
|
||||||
|
|
||||||
|
@Module
|
||||||
|
@InstallIn(SingletonComponent::class)
|
||||||
|
internal interface LastSignedWalletFormStoreModule {
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
fun bindLastSignedWalletFormStore(impl: SendTransactionSignerInfoInterceptor): LastSignedWalletFormStore
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
package com.tangem.core.analytics.paramsinterceptor
|
||||||
|
|
||||||
|
import com.tangem.core.analytics.api.ParamsInterceptor
|
||||||
|
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||||
|
import com.tangem.core.analytics.models.AnalyticsParam
|
||||||
|
import com.tangem.core.analytics.models.Basic
|
||||||
|
import com.tangem.core.analytics.store.LastSignedWalletFormStore
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
class SendTransactionSignerInfoInterceptor @Inject constructor() :
|
||||||
|
ParamsInterceptor,
|
||||||
|
LastSignedWalletFormStore {
|
||||||
|
|
||||||
|
private val walletForm = MutableStateFlow(Basic.TransactionSent.WalletForm.Card)
|
||||||
|
|
||||||
|
override fun update(form: Basic.TransactionSent.WalletForm) {
|
||||||
|
walletForm.value = form
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun id(): String = ID
|
||||||
|
|
||||||
|
override fun canBeAppliedTo(event: AnalyticsEvent): Boolean = event is Basic.TransactionSent
|
||||||
|
|
||||||
|
override fun intercept(params: MutableMap<String, String>) {
|
||||||
|
params[AnalyticsParam.WALLET_FORM] = walletForm.value.name
|
||||||
|
}
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
const val ID = "SendTransactionSignerInfoInterceptor"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
package com.tangem.core.analytics.store
|
||||||
|
|
||||||
|
import com.tangem.core.analytics.models.Basic
|
||||||
|
|
||||||
|
interface LastSignedWalletFormStore {
|
||||||
|
|
||||||
|
fun update(form: Basic.TransactionSent.WalletForm)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,83 @@
|
||||||
|
package com.tangem.core.analytics.paramsinterceptor
|
||||||
|
|
||||||
|
import com.google.common.truth.Truth
|
||||||
|
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||||
|
import com.tangem.core.analytics.models.AnalyticsParam
|
||||||
|
import com.tangem.core.analytics.models.Basic
|
||||||
|
import io.mockk.mockk
|
||||||
|
import org.junit.jupiter.api.BeforeEach
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.junit.jupiter.api.TestInstance
|
||||||
|
|
||||||
|
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||||
|
internal class SendTransactionSignerInfoInterceptorTest {
|
||||||
|
|
||||||
|
private lateinit var interceptor: SendTransactionSignerInfoInterceptor
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
fun setUp() {
|
||||||
|
interceptor = SendTransactionSignerInfoInterceptor()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `id returns stable identifier`() {
|
||||||
|
Truth.assertThat(interceptor.id()).isEqualTo("SendTransactionSignerInfoInterceptor")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `canBeAppliedTo returns true for TransactionSent event`() {
|
||||||
|
val event = mockk<Basic.TransactionSent>()
|
||||||
|
|
||||||
|
Truth.assertThat(interceptor.canBeAppliedTo(event)).isTrue()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `canBeAppliedTo returns false for any other event`() {
|
||||||
|
val event = mockk<AnalyticsEvent>()
|
||||||
|
|
||||||
|
Truth.assertThat(interceptor.canBeAppliedTo(event)).isFalse()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `intercept writes Card by default`() {
|
||||||
|
val params = mutableMapOf<String, String>()
|
||||||
|
|
||||||
|
interceptor.intercept(params)
|
||||||
|
|
||||||
|
Truth.assertThat(params[AnalyticsParam.WALLET_FORM])
|
||||||
|
.isEqualTo(Basic.TransactionSent.WalletForm.Card.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `intercept writes last updated wallet form`() {
|
||||||
|
interceptor.update(Basic.TransactionSent.WalletForm.Ring)
|
||||||
|
val params = mutableMapOf<String, String>()
|
||||||
|
|
||||||
|
interceptor.intercept(params)
|
||||||
|
|
||||||
|
Truth.assertThat(params[AnalyticsParam.WALLET_FORM])
|
||||||
|
.isEqualTo(Basic.TransactionSent.WalletForm.Ring.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `update overrides previous wallet form`() {
|
||||||
|
interceptor.update(Basic.TransactionSent.WalletForm.Ring)
|
||||||
|
interceptor.update(Basic.TransactionSent.WalletForm.Card)
|
||||||
|
val params = mutableMapOf<String, String>()
|
||||||
|
|
||||||
|
interceptor.intercept(params)
|
||||||
|
|
||||||
|
Truth.assertThat(params[AnalyticsParam.WALLET_FORM])
|
||||||
|
.isEqualTo(Basic.TransactionSent.WalletForm.Card.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `intercept preserves other params`() {
|
||||||
|
val params = mutableMapOf("Source" to "Send")
|
||||||
|
|
||||||
|
interceptor.intercept(params)
|
||||||
|
|
||||||
|
Truth.assertThat(params).containsEntry("Source", "Send")
|
||||||
|
Truth.assertThat(params).containsKey(AnalyticsParam.WALLET_FORM)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue