Updated on 2026-08-14
This commit is contained in:
commit
eec7f2ffc0
35 changed files with 234 additions and 25 deletions
|
|
@ -1,8 +1,13 @@
|
|||
package com.tangem.tap.di
|
||||
|
||||
import android.content.Context
|
||||
import com.tangem.core.analytics.api.AnalyticsExceptionHandler
|
||||
import com.tangem.core.decompose.di.GlobalUiMessageSender
|
||||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
import com.tangem.core.navigation.finisher.AppFinisher
|
||||
import com.tangem.domain.card.BuildConfig
|
||||
import com.tangem.domain.card.repository.CardSdkConfigRepository
|
||||
import com.tangem.domain.feedback.SendFeedbackEmailUseCase
|
||||
import com.tangem.features.onboarding.v2.OnboardingV2FeatureToggles
|
||||
import com.tangem.sdk.api.TangemSdkManager
|
||||
import com.tangem.tap.domain.sdk.impl.DefaultTangemSdkManager
|
||||
|
|
@ -10,6 +15,7 @@ import com.tangem.tap.domain.sdk.impl.MockTangemSdkManager
|
|||
import com.tangem.tap.domain.tasks.visa.TangemPayGenerateAddressAndSignChallengeTask
|
||||
import com.tangem.tap.domain.tasks.visa.VisaCardActivationTask
|
||||
import com.tangem.tap.domain.visa.VisaCardScanHandler
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
|
|
@ -30,6 +36,11 @@ internal class TangemSdkManagerModule {
|
|||
visaCardActivationTaskFactory: VisaCardActivationTask.Factory,
|
||||
tangemPayChallengeTaskFactory: TangemPayGenerateAddressAndSignChallengeTask.Factory,
|
||||
onboardingV2FeatureToggles: OnboardingV2FeatureToggles,
|
||||
@GlobalUiMessageSender uiMessageSender: UiMessageSender,
|
||||
appFinisher: AppFinisher,
|
||||
sendFeedbackEmailUseCase: SendFeedbackEmailUseCase,
|
||||
analyticsExceptionHandler: AnalyticsExceptionHandler,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
): TangemSdkManager {
|
||||
return if (BuildConfig.MOCK_DATA_SOURCE) {
|
||||
MockTangemSdkManager(resources = context.resources)
|
||||
|
|
@ -41,6 +52,11 @@ internal class TangemSdkManagerModule {
|
|||
visaCardActivationTaskFactory = visaCardActivationTaskFactory,
|
||||
tangemPayChallengeTaskFactory = tangemPayChallengeTaskFactory,
|
||||
onboardingV2FeatureToggles = onboardingV2FeatureToggles,
|
||||
uiMessageSender = uiMessageSender,
|
||||
appFinisher = appFinisher,
|
||||
sendFeedbackEmailUseCase = sendFeedbackEmailUseCase,
|
||||
analyticsExceptionHandler = analyticsExceptionHandler,
|
||||
dispatchers = dispatchers,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,12 +18,21 @@ import com.tangem.common.extensions.hexToBytes
|
|||
import com.tangem.common.services.secure.SecureStorage
|
||||
import com.tangem.common.usersCode.UserCodeRepository
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.core.analytics.api.AnalyticsExceptionHandler
|
||||
import com.tangem.core.analytics.models.ExceptionAnalyticsEvent
|
||||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
import com.tangem.core.navigation.finisher.AppFinisher
|
||||
import com.tangem.core.res.getStringSafe
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.message.DialogMessage
|
||||
import com.tangem.core.ui.message.EventMessageAction
|
||||
import com.tangem.crypto.bip39.DefaultMnemonic
|
||||
import com.tangem.crypto.hdWallet.DerivationPath
|
||||
import com.tangem.crypto.hdWallet.bip32.ExtendedPublicKey
|
||||
import com.tangem.domain.card.common.util.cardTypesResolver
|
||||
import com.tangem.domain.card.repository.CardSdkConfigRepository
|
||||
import com.tangem.domain.feedback.SendFeedbackEmailUseCase
|
||||
import com.tangem.domain.feedback.models.FeedbackEmailType
|
||||
import com.tangem.domain.models.scan.CardDTO
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
|
|
@ -57,13 +66,14 @@ import com.tangem.tap.domain.twins.CreateFirstTwinWalletTask
|
|||
import com.tangem.tap.domain.twins.CreateSecondTwinWalletTask
|
||||
import com.tangem.tap.domain.twins.FinalizeTwinTask
|
||||
import com.tangem.tap.domain.visa.VisaCardScanHandler
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.wallet.R
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import kotlin.coroutines.resume
|
||||
|
||||
@Suppress("TooManyFunctions", "LargeClass")
|
||||
@Suppress("TooManyFunctions", "LargeClass", "LongParameterList")
|
||||
internal class DefaultTangemSdkManager(
|
||||
private val cardSdkConfigRepository: CardSdkConfigRepository,
|
||||
private val resources: Resources,
|
||||
|
|
@ -71,6 +81,11 @@ internal class DefaultTangemSdkManager(
|
|||
private val visaCardActivationTaskFactory: VisaCardActivationTask.Factory,
|
||||
private val tangemPayChallengeTaskFactory: TangemPayGenerateAddressAndSignChallengeTask.Factory,
|
||||
private val onboardingV2FeatureToggles: OnboardingV2FeatureToggles,
|
||||
private val uiMessageSender: UiMessageSender,
|
||||
private val appFinisher: AppFinisher,
|
||||
private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase,
|
||||
private val analyticsExceptionHandler: AnalyticsExceptionHandler,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
) : TangemSdkManager {
|
||||
|
||||
private val awaitInitializationMutex = Mutex()
|
||||
|
|
@ -99,6 +114,8 @@ internal class DefaultTangemSdkManager(
|
|||
override val userCodeRequestPolicy: UserCodeRequestPolicy
|
||||
get() = tangemSdk.config.userCodeRequestPolicy
|
||||
|
||||
private val coroutineScope = CoroutineScope(SupervisorJob() + dispatchers.io)
|
||||
|
||||
override suspend fun checkNeedEnrollBiometrics(awaitInitialization: Boolean): Boolean {
|
||||
return try {
|
||||
needEnrollBiometrics
|
||||
|
|
@ -413,9 +430,16 @@ internal class DefaultTangemSdkManager(
|
|||
break
|
||||
} else {
|
||||
if (attemps++ >= MAX_INITIALIZE_ATTEMPTS) {
|
||||
error("Can't initialize authentication manager after $MAX_INITIALIZE_ATTEMPTS attempts")
|
||||
analyticsExceptionHandler.sendException(
|
||||
ExceptionAnalyticsEvent(
|
||||
exception = IllegalStateException(
|
||||
"Can't initialize authentication manager after $MAX_INITIALIZE_ATTEMPTS attempts",
|
||||
),
|
||||
),
|
||||
)
|
||||
showAlert()
|
||||
} else {
|
||||
delay(timeMillis = 200)
|
||||
delay(timeMillis = 400)
|
||||
}
|
||||
}
|
||||
} while (true)
|
||||
|
|
@ -424,6 +448,28 @@ internal class DefaultTangemSdkManager(
|
|||
}
|
||||
}
|
||||
|
||||
private fun showAlert() {
|
||||
uiMessageSender.send(
|
||||
message = DialogMessage(
|
||||
message = resourceReference(id = R.string.alert_authentication_error_message),
|
||||
title = resourceReference(id = R.string.alert_authentication_error_title),
|
||||
isDismissable = false,
|
||||
dismissOnFirstAction = false,
|
||||
firstActionBuilder = {
|
||||
EventMessageAction(
|
||||
title = resourceReference(R.string.alert_button_request_support),
|
||||
onClick = {
|
||||
coroutineScope.launch {
|
||||
sendFeedbackEmailUseCase(FeedbackEmailType.BiometricsAuthenticationFailed)
|
||||
}
|
||||
},
|
||||
)
|
||||
},
|
||||
secondActionBuilder = { cancelAction(onClick = appFinisher::finish) },
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// region Twin-specific
|
||||
|
||||
override suspend fun createFirstTwinWallet(
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
package com.tangem.core.analytics.models
|
||||
|
||||
import com.tangem.core.analytics.models.AnalyticsParam.Key.REFERRAL
|
||||
import com.tangem.core.analytics.models.AnalyticsParam.Key.REFERRAL_ID
|
||||
|
||||
const val IS_NOT_HTTP_ERROR = "Is not http error"
|
||||
|
||||
sealed class AnalyticsParam {
|
||||
|
|
@ -287,5 +290,12 @@ sealed class AnalyticsParam {
|
|||
const val ACCOUNT_DERIVATION_TO = "Account Derivation (to)"
|
||||
const val FEE_TOKEN = "Fee Token"
|
||||
const val ACCOUNT_DERIVATION = "Account Derivation"
|
||||
const val REFERRAL = "Referral"
|
||||
const val REFERRAL_ID = "Referral_ID"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getReferralParams(referralId: String?): List<Pair<String, String>> = listOf(
|
||||
REFERRAL to (!referralId.isNullOrBlank()).toString().replaceFirstChar(Char::titlecase),
|
||||
REFERRAL_ID to (referralId ?: "Empty"),
|
||||
)
|
||||
|
|
@ -3,6 +3,7 @@ package com.tangem.core.analytics.models.event
|
|||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.AnalyticsParam
|
||||
import com.tangem.core.analytics.models.AppsFlyerIncludedEvent
|
||||
import com.tangem.core.analytics.models.getReferralParams
|
||||
|
||||
sealed class OnboardingAnalyticsEvent(
|
||||
category: String,
|
||||
|
|
@ -55,6 +56,7 @@ sealed class OnboardingAnalyticsEvent(
|
|||
creationType: WalletCreationType = WalletCreationType.NewSeed,
|
||||
seedPhraseLength: Int? = null,
|
||||
passPhraseState: AnalyticsParam.EmptyFull,
|
||||
referralId: String?,
|
||||
) : CreateWallet(
|
||||
event = "Wallet Created Successfully",
|
||||
params = buildMap {
|
||||
|
|
@ -64,6 +66,7 @@ sealed class OnboardingAnalyticsEvent(
|
|||
if (seedPhraseLength != null) {
|
||||
put("Seed Phrase Length", seedPhraseLength.toString())
|
||||
}
|
||||
putAll(getReferralParams(referralId))
|
||||
},
|
||||
), AppsFlyerIncludedEvent
|
||||
|
||||
|
|
|
|||
|
|
@ -86,6 +86,8 @@
|
|||
<string name="address_qr_code_message_format">Sende nur %1$s ( %2$s ) vom %3$s -Netzwerk an diese Adresse. Die Verwendung anderer Token und Netzwerke kann zum Verlust von Geldern führen.</string>
|
||||
<string name="address_type_default">Standard</string>
|
||||
<string name="address_type_legacy">Altbestand</string>
|
||||
<string name="alert_authentication_error_message">Bei der biometrischen Authentifizierung ist ein Fehler aufgetreten. Bitte setzen Sie die Biometrie auf Ihrem Gerät zurück oder kontaktieren Sie den Support.</string>
|
||||
<string name="alert_authentication_error_title">Authentifizierungsfehler</string>
|
||||
<string name="alert_button_how_to_scan">So scannt man</string>
|
||||
<string name="alert_button_request_support">Hilfe anfordern</string>
|
||||
<string name="alert_button_try_again">Erneut versuchen</string>
|
||||
|
|
@ -299,6 +301,7 @@
|
|||
<string name="common_go_to_token">Zum Token</string>
|
||||
<string name="common_got_it">Verstanden</string>
|
||||
<string name="common_hide">Ausblenden</string>
|
||||
<string name="common_hold_to">Halten bis %s</string>
|
||||
<string name="common_hour">Stunde</string>
|
||||
<string name="common_import">Importieren</string>
|
||||
<string name="common_in_progress">In Arbeit</string>
|
||||
|
|
@ -374,6 +377,7 @@
|
|||
<string name="common_swap">Tauschen</string>
|
||||
<string name="common_tangem">Tangem</string>
|
||||
<string name="common_tangem_wallet">Tangem Wallet</string>
|
||||
<string name="common_tap_and_hold_hint">Tippen und halten</string>
|
||||
<string name="common_terms_and_conditions">Allgemeine Geschäftsbedingungen</string>
|
||||
<string name="common_terms_of_use">Nutzungsbedingungen</string>
|
||||
<string name="common_to">An</string>
|
||||
|
|
@ -463,6 +467,11 @@
|
|||
<string name="domain_receive_assets_onboarding_description">Das Senden von Vermögenswerten in anderen Netzwerken führt zu dauerhaftem Verlust.</string>
|
||||
<string name="domain_receive_assets_onboarding_network_name">%s Netzwerk</string>
|
||||
<string name="domain_receive_assets_onboarding_title">Sende Geld nur mit</string>
|
||||
<string name="earn_best_opportunities">Beste Gelegenheiten</string>
|
||||
<string name="earn_filter_all_networks">Alle Netzwerke</string>
|
||||
<string name="earn_filter_all_types">Alle Arten</string>
|
||||
<string name="earn_mostly_used">Meist verwendet</string>
|
||||
<string name="earn_title">Verdienen</string>
|
||||
<string name="email_preface_wc_error">Hallo Support-Team, ich habe einen Fehler mit dem Code %s festgestellt.</string>
|
||||
<string name="email_subject_wc_error">WalletConnect-Fehler</string>
|
||||
<string name="error_wrong_wallet_tapped">Du hast eine Karte oder Ring aus einer anderen Wallet verwendet. Tippe auf die Karte oder Ring, die dieser Wallet zugeordnet ist.</string>
|
||||
|
|
@ -613,6 +622,7 @@
|
|||
<string name="hw_backup_need_title">Zuerst die Sicherung abschließen</string>
|
||||
<string name="hw_backup_no_backup">Unvollständig</string>
|
||||
<string name="hw_backup_section_other_title">Andere Methoden</string>
|
||||
<string name="hw_backup_seed_code_description">Bewahre Deine Wiederherstellungsphrase an einem sicheren Ort auf und halte diese geheim, um Dein Guthaben zu schützen. Richte außerdem einen 8 stelligen Zugangscode für zusätzliche Sicherheit ein.</string>
|
||||
<string name="hw_backup_seed_description">Speicher Deinen Wiederherstellungssatz an einem sicheren Ort und halte diesen stets geheim, um Dein Geld zu schützen.</string>
|
||||
<string name="hw_backup_seed_title">Wiederherstellungs-Phrase</string>
|
||||
<string name="hw_backup_to_secure_description">Um Deine Wallet mit einem Zugangscode zu sichern, schließe den Sicherungsvorgang ab.</string>
|
||||
|
|
@ -1463,6 +1473,9 @@
|
|||
<string name="tangem_pay_freeze_card_freeze">Einfrieren</string>
|
||||
<string name="tangem_pay_freeze_card_success">Ihre Karte ist eingefroren.</string>
|
||||
<string name="tangem_pay_get_help">Hilfe erhalten</string>
|
||||
<string name="tangem_pay_history_item_spend_mc_declined_reason">Grund: %s</string>
|
||||
<string name="tangem_pay_history_item_spend_mc_title_format" formatted="false">%s · %s</string>
|
||||
<string name="tangem_pay_history_item_spend_mcc">MCC %s</string>
|
||||
<string name="tangem_pay_other">Andere</string>
|
||||
<string name="tangem_pay_rooted_device_subtitle">Nicht nutzbar auf gerooteten Geräten</string>
|
||||
<string name="tangem_pay_status_completed">Abgeschlossen</string>
|
||||
|
|
@ -1834,7 +1847,18 @@
|
|||
<string name="warning_button_ok">OK, habe ich verstanden!</string>
|
||||
<string name="warning_button_really_cool">Echt toll!</string>
|
||||
<string name="warning_button_refresh">Aktualisieren</string>
|
||||
<string name="warning_clore_migration_button">Migration starten</string>
|
||||
<string name="warning_clore_migration_copy_button">Kopie</string>
|
||||
<string name="warning_clore_migration_description">Um weiterhin Zugriff auf Deine Gelder zu haben, beginne die Migration gemäß den offiziellen Clore-Richtlinien.</string>
|
||||
<string name="warning_clore_migration_error_signing_not_supported">Die Nachrichtensignatur wird für dieses Netzwerk nicht unterstützt.</string>
|
||||
<string name="warning_clore_migration_error_wallet_manager_not_found">Nachricht konnte nicht signiert werden. Bitte versuche es erneut.</string>
|
||||
<string name="warning_clore_migration_message">Laut der offiziellen Dokumentation von Clore werden alle Münzen, die vor dem 21. Dezember erhalten wurden, in Clore (ERC-20 Token) migriert; Münzen, die nach diesem Datum erhalten wurden, nicht. Eine Lösung für den Transfer ist in Arbeit — bleibt dran.</string>
|
||||
<string name="warning_clore_migration_message_label">Nachricht</string>
|
||||
<string name="warning_clore_migration_open_portal_button">Claim-Portal öffnen</string>
|
||||
<string name="warning_clore_migration_sheet_description">Um Deine Clore-Token weiterhin nutzen zu können, musst Du die Token-Migration gemäß den Informationen im Claim Portal durchführen.</string>
|
||||
<string name="warning_clore_migration_sheet_title">Clore-Netzwerkmigration</string>
|
||||
<string name="warning_clore_migration_sign_button">signieren</string>
|
||||
<string name="warning_clore_migration_signature_label">Unterschrift</string>
|
||||
<string name="warning_clore_migration_title">Migration des Clore-Netzwerks</string>
|
||||
<string name="warning_demo_mode_message">Du befindest sich derzeit im Demo-Modus</string>
|
||||
<string name="warning_demo_mode_title">Demo-Modus aktiv</string>
|
||||
|
|
|
|||
|
|
@ -86,6 +86,8 @@
|
|||
<string name="address_qr_code_message_format">Envíe solo %1$s (%2$s) desde redes como %3$s a esta dirección. Usar otros tokens y redes puede resultar en la pérdida de fondos.</string>
|
||||
<string name="address_type_default">Por defecto</string>
|
||||
<string name="address_type_legacy">Legacy</string>
|
||||
<string name="alert_authentication_error_message">Algo salió mal con la biometría. Por favor, intente restablecer la biometría en su dispositivo o contacte con soporte.</string>
|
||||
<string name="alert_authentication_error_title">Error de inicio de sesión</string>
|
||||
<string name="alert_button_how_to_scan">Cómo escanear</string>
|
||||
<string name="alert_button_request_support">Solicitar soporte</string>
|
||||
<string name="alert_button_try_again">Inténtelo de nuevo</string>
|
||||
|
|
|
|||
|
|
@ -86,6 +86,8 @@
|
|||
<string name="address_qr_code_message_format">Envoyez uniquement %1$s (%2$s) depuis les réseaux %3$s à cette adresse. L\'utilisation d\'autres jetons et réseaux peut entraîner une perte de fonds.</string>
|
||||
<string name="address_type_default">Défaut</string>
|
||||
<string name="address_type_legacy">Héritage</string>
|
||||
<string name="alert_authentication_error_message">Quelque chose s’est mal passé avec la biométrie. Veuillez réinitialiser la biométrie sur votre appareil ou contacter le support.</string>
|
||||
<string name="alert_authentication_error_title">Erreur d’authentification</string>
|
||||
<string name="alert_button_how_to_scan">Comment scanner</string>
|
||||
<string name="alert_button_request_support">Demander de l\'aide</string>
|
||||
<string name="alert_button_try_again">Réessayez</string>
|
||||
|
|
@ -1845,7 +1847,17 @@
|
|||
<string name="warning_button_ok">Ok, compris!</string>
|
||||
<string name="warning_button_really_cool">Vraiment cool !</string>
|
||||
<string name="warning_button_refresh">Rafraîchir</string>
|
||||
<string name="warning_clore_migration_button">Lancer la migration</string>
|
||||
<string name="warning_clore_migration_copy_button">Copier</string>
|
||||
<string name="warning_clore_migration_error_signing_not_supported">La signature des messages n\'est pas prise en charge pour ce réseau.</string>
|
||||
<string name="warning_clore_migration_error_wallet_manager_not_found">Impossible de signer le message. Veuillez réessayer.</string>
|
||||
<string name="warning_clore_migration_message">Selon la documentation officielle de Clore, toutes les pièces reçues avant le 21 décembre seront migrées vers Clore (token ERC-20) ; les pièces reçues après cette date ne le seront pas. Une solution de transfert arrive — restez à l\'écoute.</string>
|
||||
<string name="warning_clore_migration_message_label">Message</string>
|
||||
<string name="warning_clore_migration_open_portal_button">Ouvrir le portail des réclamations</string>
|
||||
<string name="warning_clore_migration_sheet_description">Pour continuer à utiliser vos jetons Clore, vous devez effectuer la migration des jetons conformément aux informations fournies sur le portail de réclamation.</string>
|
||||
<string name="warning_clore_migration_sheet_title">Migration du réseau Clore</string>
|
||||
<string name="warning_clore_migration_sign_button">Signer</string>
|
||||
<string name="warning_clore_migration_signature_label">Signature</string>
|
||||
<string name="warning_clore_migration_title">Migration du réseau Clore</string>
|
||||
<string name="warning_demo_mode_message">Vous êtes actuellement en mode démo</string>
|
||||
<string name="warning_demo_mode_title">Mode démo actif</string>
|
||||
|
|
|
|||
|
|
@ -86,6 +86,8 @@
|
|||
<string name="address_qr_code_message_format">このアドレスには%3$s ネットワークから%1$s (%2$s) のみを送信してください。他のトークンやネットワークを使用すると、資金を失う可能性があります。</string>
|
||||
<string name="address_type_default">デフォルト</string>
|
||||
<string name="address_type_legacy">レガシー</string>
|
||||
<string name="alert_authentication_error_message">デバイスの生体認証をリセットするか、サポートにお問い合わせください</string>
|
||||
<string name="alert_authentication_error_title">認証エラー</string>
|
||||
<string name="alert_button_how_to_scan">スキャン方法</string>
|
||||
<string name="alert_button_request_support">サポートをリクエストする</string>
|
||||
<string name="alert_button_try_again">もう一度やり直してください</string>
|
||||
|
|
@ -523,7 +525,7 @@
|
|||
<string name="express_provider">プロバイダー</string>
|
||||
<string name="express_provider_best_rate">ベストレート</string>
|
||||
<string name="express_provider_fca_warning_list">FCA警告リスト</string>
|
||||
<string name="express_provider_great_rate">最適な選択</string>
|
||||
<string name="express_provider_great_rate">お得なレート</string>
|
||||
<string name="express_provider_in_fca_warning_list">FCA警告リストに掲載されたプロバイダー</string>
|
||||
<string name="express_provider_max_amount">最大 %s まで使用可能</string>
|
||||
<string name="express_provider_min_amount">%s 以上で利用可能</string>
|
||||
|
|
@ -724,7 +726,7 @@
|
|||
<string name="markets_loading_no_data_title">データなし</string>
|
||||
<string name="markets_pulse_common_title">マーケット動向</string>
|
||||
<string name="markets_quick_actions">クイックアクション</string>
|
||||
<string name="markets_search_header_title">マーケットから探す</string>
|
||||
<string name="markets_search_header_title">トークンを探す</string>
|
||||
<string name="markets_search_result_title">結果</string>
|
||||
<string name="markets_search_see_tokens_under_100k">時価総額10万ドル以下のトークンを見る</string>
|
||||
<string name="markets_search_show_tokens">トークンを表示</string>
|
||||
|
|
@ -741,8 +743,8 @@
|
|||
<string name="markets_sort_by_experienced_buyers_title">経験豊富な買い手</string>
|
||||
<string name="markets_sort_by_rating_title">時価総額</string>
|
||||
<string name="markets_sort_by_title">並べ替え</string>
|
||||
<string name="markets_sort_by_top_gainers_title">上昇率上位</string>
|
||||
<string name="markets_sort_by_top_losers_title">下落率上位</string>
|
||||
<string name="markets_sort_by_top_gainers_title">値上がり</string>
|
||||
<string name="markets_sort_by_top_losers_title">値下がり</string>
|
||||
<string name="markets_sort_by_trending_title">トレンド</string>
|
||||
<string name="markets_sort_by_yield_mode_title">利息モード</string>
|
||||
<string name="markets_staking_banner_description_placeholder">ステーキングは暗号資産で報酬を受け取る最も簡単な方法です。 %s</string>
|
||||
|
|
@ -770,7 +772,7 @@
|
|||
<string name="markets_token_details_exchanges_title">取引所</string>
|
||||
<string name="markets_token_details_experienced_buyers">経験豊富な買い手</string>
|
||||
<string name="markets_token_details_experienced_buyers_description">少なくとも100の発信取引を持つネット・バイヤー</string>
|
||||
<string name="markets_token_details_experienced_buyers_full">経験豊富な買い手</string>
|
||||
<string name="markets_token_details_experienced_buyers_full">アクティブ投資家数</string>
|
||||
<string name="markets_token_details_fully_diluted_valuation">完全希薄化後評価額</string>
|
||||
<string name="markets_token_details_fully_diluted_valuation_description">現在流通していないものも含め、存在する可能性のあるすべてのコインが流通している場合の暗号資産の理論上の合計価値</string>
|
||||
<string name="markets_token_details_fully_diluted_valuation_full">完全希薄化後評価額</string>
|
||||
|
|
@ -895,7 +897,7 @@
|
|||
<string name="notification_visa_waitlist_promo_text">事前申し込み受付中。他にない特別なカードを、いち早く体験しよう。</string>
|
||||
<string name="notification_visa_waitlist_promo_title">Tangem Visaカード</string>
|
||||
<string name="notification_yield_promo_button">利用規約</string>
|
||||
<string name="notification_yield_promo_text">100ドル以上を入金し、30日間保持すると、10ドルを受け取れます。</string>
|
||||
<string name="notification_yield_promo_text">$100以上を入金して30日間保有すると、$10を受け取れます</string>
|
||||
<string name="notification_yield_promo_title">Yield Mode キャンペーンに参加しよう!</string>
|
||||
<string name="onboarding_access_code_feature_1_description">すべてのデバイスを保護するには、単一のアクセスコードを設定してください。</string>
|
||||
<string name="onboarding_access_code_feature_1_title">保護する</string>
|
||||
|
|
@ -1011,7 +1013,7 @@
|
|||
<string name="onramp_max_amount_restriction">買付金額は%s以下にしてください</string>
|
||||
<string name="onramp_min_amount_restriction">買付金額は少なくとも%sである必要があります</string>
|
||||
<string name="onramp_no_available_providers">この通貨で利用可能なプロバイダーはありません</string>
|
||||
<string name="onramp_offer_type_fastet">最速</string>
|
||||
<string name="onramp_offer_type_fastet">最短処理</string>
|
||||
<string name="onramp_pay_with">支払う</string>
|
||||
<string name="onramp_payment_method_subtitle">支払方法</string>
|
||||
<string name="onramp_provider_max_amount">最大 %s まで使用可能</string>
|
||||
|
|
@ -1598,7 +1600,7 @@
|
|||
<string name="token_swap_changelly_promotion_message">このトークンは、2月%2$s-%3$s の間、%1$s のサービス手数料で別のトークンと交換できます。</string>
|
||||
<string name="token_swap_changelly_promotion_title">Changellyでスワップ、手数料%s</string>
|
||||
<string name="token_swap_promotion_button">今すぐスワップ</string>
|
||||
<string name="tokens_list_hot_crypto_header">ホットな暗号資産🔥</string>
|
||||
<string name="tokens_list_hot_crypto_header">市場トレンド🔥</string>
|
||||
<string name="tokens_list_unavailable_to_purchase_header">買付できません</string>
|
||||
<string name="tokens_list_unavailable_to_sell_header">売却できません</string>
|
||||
<string name="tokens_list_unavailable_to_swap_header">%sからのスワップは利用できません</string>
|
||||
|
|
@ -1825,7 +1827,18 @@
|
|||
<string name="warning_button_ok">はい、わかりました!</string>
|
||||
<string name="warning_button_really_cool">すごくクールだ!</string>
|
||||
<string name="warning_button_refresh">リフレッシュ</string>
|
||||
<string name="warning_clore_migration_button">移行を開始</string>
|
||||
<string name="warning_clore_migration_copy_button">コピー</string>
|
||||
<string name="warning_clore_migration_description">資金へのアクセスを維持するため、Cloreの公式ガイドラインに従って移行を開始してください。</string>
|
||||
<string name="warning_clore_migration_error_signing_not_supported">このネットワークではメッセージ署名はサポートされていません</string>
|
||||
<string name="warning_clore_migration_error_wallet_manager_not_found">メッセージに署名できません。もう一度お試しください。</string>
|
||||
<string name="warning_clore_migration_message">Cloreの公式ドキュメントによると、12月21日以前に受け取ったすべてのコインは Clore(ERC-20トークン)へ移行されますが、同日以降に受け取ったコインは移行されません。送金(移行)ソリューションは現在準備中です。続報をお待ちください。</string>
|
||||
<string name="warning_clore_migration_message_label">メッセージ</string>
|
||||
<string name="warning_clore_migration_open_portal_button">Claim Portalを開く</string>
|
||||
<string name="warning_clore_migration_sheet_description">Cloreトークンを引き続き使用するには、Claim Portalの案内に従ってトークン移行を完了する必要があります。</string>
|
||||
<string name="warning_clore_migration_sheet_title">Cloreネットワーク移行</string>
|
||||
<string name="warning_clore_migration_sign_button">署名する</string>
|
||||
<string name="warning_clore_migration_signature_label">署名</string>
|
||||
<string name="warning_clore_migration_title">Cloreネットワークの移行</string>
|
||||
<string name="warning_demo_mode_message">現在デモモードです</string>
|
||||
<string name="warning_demo_mode_title">デモモードが有効になっています</string>
|
||||
|
|
|
|||
|
|
@ -86,6 +86,8 @@
|
|||
<string name="address_qr_code_message_format">Отправляйте только %1$s (%2$s) в сети %3$s на этот адрес. Использование другой сети может привести к утрате средств.</string>
|
||||
<string name="address_type_default">По умолчанию</string>
|
||||
<string name="address_type_legacy">Устаревший</string>
|
||||
<string name="alert_authentication_error_message">Произошла ошибка при работе с биометрией. Пожалуйста, попробуйте обновить биометрию на вашем устройстве или обратитесь в службу поддержки.</string>
|
||||
<string name="alert_authentication_error_title">Ошибка аутентификации</string>
|
||||
<string name="alert_button_how_to_scan">Как сканировать</string>
|
||||
<string name="alert_button_request_support">Обратиться в поддержку</string>
|
||||
<string name="alert_button_try_again">Попробовать снова</string>
|
||||
|
|
@ -476,6 +478,9 @@
|
|||
<string name="domain_receive_assets_onboarding_description">Отправка средств в другой сети может повлечь потерю средств.</string>
|
||||
<string name="domain_receive_assets_onboarding_network_name">%s сеть</string>
|
||||
<string name="domain_receive_assets_onboarding_title">Отправляйте средства, используя только</string>
|
||||
<string name="earn_filter_all_networks">Все сети</string>
|
||||
<string name="earn_filter_all_types">Все типы</string>
|
||||
<string name="earn_mostly_used">Часто используемые</string>
|
||||
<string name="email_preface_wc_error">Привет, команда поддержки, у меня возникла ошибка с кодом: %s</string>
|
||||
<string name="email_subject_wc_error">Ошибка WalletConnect</string>
|
||||
<string name="error_wrong_wallet_tapped">Вы использовали карту или кольцо от другого кошелька. Приложите карту или кольцо, связанную с этим кошельком.</string>
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@
|
|||
<string name="address_qr_code_message_format">Send only %1$s (%2$s) from %3$s network to this address. Using other tokens and networks may result in loss of funds.</string>
|
||||
<string name="address_type_default">Default</string>
|
||||
<string name="address_type_legacy">Legacy</string>
|
||||
<string name="alert_authentication_error_message">Try to reset biometrics on your device or contact support</string>
|
||||
<string name="alert_authentication_error_message">Something went wrong with biometrics. Please try resetting biometrics on your device or contact support.</string>
|
||||
<string name="alert_authentication_error_title">Authentication error</string>
|
||||
<string name="alert_button_how_to_scan">How to scan</string>
|
||||
<string name="alert_button_request_support">Request support</string>
|
||||
|
|
@ -468,9 +468,13 @@
|
|||
<string name="domain_receive_assets_onboarding_network_name">%s network</string>
|
||||
<string name="domain_receive_assets_onboarding_title">Send funds using only</string>
|
||||
<string name="earn_best_opportunities">Best opportunities</string>
|
||||
<string name="earn_clear_filter">Clear filter</string>
|
||||
<string name="earn_filter_all_networks">All networks</string>
|
||||
<string name="earn_filter_all_types">All types</string>
|
||||
<string name="earn_filter_by">Filter by</string>
|
||||
<string name="earn_filter_networks">Networks</string>
|
||||
<string name="earn_mostly_used">Mostly used</string>
|
||||
<string name="earn_no_results">No results</string>
|
||||
<string name="earn_title">Earn</string>
|
||||
<string name="email_preface_wc_error">Hi support team, I\'ve encountered an error with code: %s</string>
|
||||
<string name="email_subject_wc_error">WalletConnect error</string>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.tangem.domain.card.analytics
|
|||
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.AnalyticsParam
|
||||
import com.tangem.core.analytics.models.getReferralParams
|
||||
|
||||
sealed class IntroductionProcess(
|
||||
event: String,
|
||||
|
|
@ -13,7 +14,14 @@ sealed class IntroductionProcess(
|
|||
class ButtonBuyCards : IntroductionProcess("Button - Buy Cards")
|
||||
class ButtonScanCardLegacy : IntroductionProcess("Button - Scan Card")
|
||||
|
||||
class CreateWalletIntroScreenOpened : IntroductionProcess("Create Wallet Intro Screen Opened")
|
||||
class CreateWalletIntroScreenOpened(
|
||||
referralId: String?,
|
||||
) : IntroductionProcess(
|
||||
event = "Create Wallet Intro Screen Opened",
|
||||
params = buildMap {
|
||||
putAll(getReferralParams(referralId))
|
||||
},
|
||||
)
|
||||
|
||||
class ButtonScanCard(
|
||||
val source: AnalyticsParam.ScreensSources,
|
||||
|
|
|
|||
|
|
@ -59,6 +59,10 @@ sealed interface FeedbackEmailType {
|
|||
override val walletMetaInfo: WalletMetaInfo? = null
|
||||
}
|
||||
|
||||
data object BiometricsAuthenticationFailed : FeedbackEmailType {
|
||||
override val walletMetaInfo: WalletMetaInfo? = null
|
||||
}
|
||||
|
||||
sealed class Visa : FeedbackEmailType {
|
||||
abstract val customerId: String
|
||||
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ class SendFeedbackEmailUseCase(
|
|||
is FeedbackEmailType.CurrencyDescriptionError,
|
||||
is FeedbackEmailType.PreActivatedWallet,
|
||||
is FeedbackEmailType.CardAttestationFailed,
|
||||
is FeedbackEmailType.BiometricsAuthenticationFailed,
|
||||
is FeedbackEmailType.Visa.Dispute,
|
||||
is FeedbackEmailType.Visa.DisputeV2,
|
||||
is FeedbackEmailType.Visa.FeatureIsBeta,
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ class EmailMessageBodyResolver(
|
|||
is FeedbackEmailType.BackupProblem -> addUserRequestBody(type.walletMetaInfo)
|
||||
is FeedbackEmailType.ScanningProblem,
|
||||
is FeedbackEmailType.CardAttestationFailed,
|
||||
is FeedbackEmailType.BiometricsAuthenticationFailed,
|
||||
-> addPhoneInfoBody()
|
||||
is FeedbackEmailType.Visa.Activation -> addUserRequestBody(type.walletMetaInfo)
|
||||
is FeedbackEmailType.Visa.DirectUserRequest -> addUserRequestBody(type.walletMetaInfo)
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ internal class EmailMessageTitleResolver(private val resources: Resources) {
|
|||
is FeedbackEmailType.TransactionSendingProblem,
|
||||
is FeedbackEmailType.StakingProblem,
|
||||
is FeedbackEmailType.SwapProblem,
|
||||
is FeedbackEmailType.BiometricsAuthenticationFailed,
|
||||
-> R.string.feedback_preface_tx_failed
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ internal class EmailSubjectResolver(private val resources: Resources) {
|
|||
resources.getStringSafe(R.string.feedback_token_description_error)
|
||||
}
|
||||
FeedbackEmailType.CardAttestationFailed -> "Card attestation failed"
|
||||
FeedbackEmailType.BiometricsAuthenticationFailed -> "Biometrics authentication failed"
|
||||
is FeedbackEmailType.Visa.Activation -> "[Visa] [Activation] {auto-filled subject}"
|
||||
is FeedbackEmailType.Visa.DirectUserRequest -> "[Visa] {auto-filled subject}"
|
||||
is FeedbackEmailType.Visa.FailedIssueCard -> "[Visa] {auto-filled subject}"
|
||||
|
|
|
|||
|
|
@ -5,9 +5,12 @@ import com.tangem.domain.models.wallet.UserWallet
|
|||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.domain.wallets.legacy.asLockable
|
||||
import com.tangem.domain.wallets.legacy.isLockedSync
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
class GetSavedWalletsCountUseCase(
|
||||
|
|
@ -16,9 +19,14 @@ class GetSavedWalletsCountUseCase(
|
|||
private val useNewRepository: Boolean,
|
||||
) {
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
operator fun invoke(): Flow<List<UserWallet>> {
|
||||
if (useNewRepository) {
|
||||
return userWalletsListRepository.userWallets.map { requireNotNull(it) }
|
||||
return flowOf(Unit)
|
||||
.flatMapLatest {
|
||||
userWalletsListRepository.load()
|
||||
userWalletsListRepository.userWallets.map { wallets -> requireNotNull(wallets) }
|
||||
}
|
||||
}
|
||||
|
||||
return userWalletsListManager.savedWalletsCount
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ dependencies {
|
|||
implementation(projects.domain.wallets)
|
||||
implementation(projects.domain.models)
|
||||
implementation(projects.domain.hotWallet)
|
||||
implementation(projects.domain.wallets.models)
|
||||
|
||||
/** Core modules */
|
||||
implementation(projects.core.configToggles)
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import com.tangem.core.ui.R
|
|||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.message.DialogMessage
|
||||
import com.tangem.core.ui.message.dialog.Dialogs.hotWalletCreationNotSupportedDialog
|
||||
import com.tangem.datasource.local.appsflyer.AppsFlyerStore
|
||||
import com.tangem.domain.card.ScanCardProcessor
|
||||
import com.tangem.domain.card.analytics.IntroductionProcess
|
||||
import com.tangem.domain.card.repository.CardSdkConfigRepository
|
||||
|
|
@ -65,6 +66,7 @@ internal class CreateWalletStartModel @Inject constructor(
|
|||
private val trackingContextProxy: TrackingContextProxy,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
private val appsFlyerStore: AppsFlyerStore,
|
||||
) : Model() {
|
||||
|
||||
private val params = paramsContainer.require<CreateWalletStartComponent.Params>()
|
||||
|
|
@ -133,9 +135,13 @@ internal class CreateWalletStartModel @Inject constructor(
|
|||
)
|
||||
|
||||
init {
|
||||
analyticsEventHandler.send(
|
||||
event = IntroductionProcess.CreateWalletIntroScreenOpened(),
|
||||
)
|
||||
modelScope.launch {
|
||||
analyticsEventHandler.send(
|
||||
event = IntroductionProcess.CreateWalletIntroScreenOpened(
|
||||
referralId = appsFlyerStore.get()?.refcode,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun onScanClick() {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import com.tangem.core.ui.extensions.resourceReference
|
|||
import com.tangem.core.ui.message.SnackbarMessage
|
||||
import com.tangem.core.ui.message.bottomSheetMessage
|
||||
import com.tangem.crypto.bip39.Mnemonic
|
||||
import com.tangem.datasource.local.appsflyer.AppsFlyerStore
|
||||
import com.tangem.domain.common.wallets.error.SaveWalletError
|
||||
import com.tangem.domain.wallets.builder.HotUserWalletBuilder
|
||||
import com.tangem.domain.wallets.usecase.SaveWalletUseCase
|
||||
|
|
@ -41,6 +42,7 @@ internal class AddExistingWalletImportModel @Inject constructor(
|
|||
private val saveUserWalletUseCase: SaveWalletUseCase,
|
||||
@GlobalUiMessageSender private val uiMessageSender: UiMessageSender,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
private val appsFlyerStore: AppsFlyerStore,
|
||||
) : Model() {
|
||||
|
||||
private val params: AddExistingWalletImportComponent.Params = paramsContainer.require()
|
||||
|
|
@ -122,6 +124,7 @@ internal class AddExistingWalletImportModel @Inject constructor(
|
|||
} else {
|
||||
AnalyticsParam.EmptyFull.Full
|
||||
},
|
||||
referralId = appsFlyerStore.get()?.refcode,
|
||||
),
|
||||
)
|
||||
params.callbacks.onWalletImported(userWallet.walletId)
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import com.tangem.core.decompose.model.ParamsContainer
|
|||
import com.tangem.core.decompose.navigation.Router
|
||||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
import com.tangem.core.ui.message.dialog.Dialogs.hotWalletCreationNotSupportedDialog
|
||||
import com.tangem.datasource.local.appsflyer.AppsFlyerStore
|
||||
import com.tangem.domain.hotwallet.IsHotWalletCreationSupported
|
||||
import com.tangem.domain.wallets.builder.HotUserWalletBuilder
|
||||
import com.tangem.domain.wallets.usecase.SaveWalletUseCase
|
||||
|
|
@ -44,6 +45,7 @@ internal class CreateMobileWalletModel @Inject constructor(
|
|||
private val isHotWalletCreationSupported: IsHotWalletCreationSupported,
|
||||
private val uiMessageSender: UiMessageSender,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
private val appsFlyerStore: AppsFlyerStore,
|
||||
) : Model() {
|
||||
|
||||
private val params: CreateMobileWalletComponent.Params = paramsContainer.require()
|
||||
|
|
@ -100,6 +102,7 @@ internal class CreateMobileWalletModel @Inject constructor(
|
|||
creationType = OnboardingAnalyticsEvent.CreateWallet.WalletCreationType.NewSeed,
|
||||
seedPhraseLength = SEED_PHRASE_LENGTH,
|
||||
passPhraseState = AnalyticsParam.EmptyFull.Empty,
|
||||
referralId = appsFlyerStore.get()?.refcode,
|
||||
),
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ package com.tangem.features.onboarding.v2.common.analytics
|
|||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.AnalyticsParam
|
||||
import com.tangem.core.analytics.models.AppsFlyerIncludedEvent
|
||||
import com.tangem.core.analytics.models.getReferralParams
|
||||
import kotlin.collections.putAll
|
||||
|
||||
sealed class OnboardingEvent(
|
||||
category: String,
|
||||
|
|
@ -25,6 +27,7 @@ sealed class OnboardingEvent(
|
|||
creationType: WalletCreationType = WalletCreationType.PrivateKey,
|
||||
seedPhraseLength: Int? = null,
|
||||
passPhraseState: AnalyticsParam.EmptyFull,
|
||||
referralId: String?,
|
||||
) : CreateWallet(
|
||||
event = "Wallet Created Successfully",
|
||||
params = buildMap {
|
||||
|
|
@ -33,6 +36,7 @@ sealed class OnboardingEvent(
|
|||
if (seedPhraseLength != null) {
|
||||
put("Seed Phrase Length", seedPhraseLength.toString())
|
||||
}
|
||||
putAll(getReferralParams(referralId))
|
||||
},
|
||||
), AppsFlyerIncludedEvent
|
||||
|
||||
|
|
|
|||
|
|
@ -9,13 +9,14 @@ import com.tangem.core.decompose.di.ModelScoped
|
|||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.core.decompose.model.ParamsContainer
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.datasource.local.appsflyer.AppsFlyerStore
|
||||
import com.tangem.domain.card.repository.CardRepository
|
||||
import com.tangem.domain.feedback.GetWalletMetaInfoUseCase
|
||||
import com.tangem.domain.feedback.SendFeedbackEmailUseCase
|
||||
import com.tangem.domain.feedback.models.FeedbackEmailType
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.wallets.builder.ColdUserWalletBuilder
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.wallets.builder.ColdUserWalletBuilder
|
||||
import com.tangem.domain.wallets.usecase.SaveWalletUseCase
|
||||
import com.tangem.features.onboarding.v2.common.analytics.OnboardingEvent
|
||||
import com.tangem.features.onboarding.v2.impl.R
|
||||
|
|
@ -45,6 +46,7 @@ internal class MultiWalletCreateWalletModel @Inject constructor(
|
|||
private val analyticsHandler: AnalyticsEventHandler,
|
||||
private val coldUserWalletBuilderFactory: ColdUserWalletBuilder.Factory,
|
||||
private val saveWalletUseCase: SaveWalletUseCase,
|
||||
private val appsFlyerStore: AppsFlyerStore,
|
||||
) : Model() {
|
||||
|
||||
private val params = paramsContainer.require<MultiWalletChildParams>()
|
||||
|
|
@ -109,6 +111,7 @@ internal class MultiWalletCreateWalletModel @Inject constructor(
|
|||
analyticsHandler.send(
|
||||
event = OnboardingEvent.CreateWallet.WalletCreatedSuccessfully(
|
||||
passPhraseState = AnalyticsParam.EmptyFull.Empty,
|
||||
referralId = appsFlyerStore.get()?.refcode,
|
||||
),
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import com.tangem.core.ui.R
|
|||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.message.SnackbarMessage
|
||||
import com.tangem.crypto.bip39.Mnemonic
|
||||
import com.tangem.datasource.local.appsflyer.AppsFlyerStore
|
||||
import com.tangem.domain.card.repository.CardRepository
|
||||
import com.tangem.domain.feedback.GetWalletMetaInfoUseCase
|
||||
import com.tangem.domain.feedback.SendFeedbackEmailUseCase
|
||||
|
|
@ -64,6 +65,7 @@ internal class MultiWalletSeedPhraseModel @Inject constructor(
|
|||
private val coldUserWalletBuilderFactory: ColdUserWalletBuilder.Factory,
|
||||
@GlobalUiMessageSender private val uiMessageSender: UiMessageSender,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
private val appsFlyerStore: AppsFlyerStore,
|
||||
) : Model() {
|
||||
|
||||
private val params = paramsContainer.require<MultiWalletChildParams>()
|
||||
|
|
@ -248,6 +250,7 @@ internal class MultiWalletSeedPhraseModel @Inject constructor(
|
|||
} else {
|
||||
AnalyticsParam.EmptyFull.Full
|
||||
},
|
||||
referralId = appsFlyerStore.get()?.refcode,
|
||||
),
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import com.tangem.core.decompose.di.ModelScoped
|
|||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.core.decompose.model.ParamsContainer
|
||||
import com.tangem.core.ui.components.artwork.ArtworkUM
|
||||
import com.tangem.datasource.local.appsflyer.AppsFlyerStore
|
||||
import com.tangem.domain.card.repository.CardRepository
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.wallets.builder.ColdUserWalletBuilder
|
||||
|
|
@ -33,6 +34,7 @@ internal class OnboardingNoteCreateWalletModel @Inject constructor(
|
|||
private val coldUserWalletBuilderFactory: ColdUserWalletBuilder.Factory,
|
||||
private val saveWalletUseCase: SaveWalletUseCase,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
private val appsFlyerStore: AppsFlyerStore,
|
||||
) : Model() {
|
||||
|
||||
private val params = paramsContainer.require<OnboardingNoteCreateWalletComponent.Params>()
|
||||
|
|
@ -68,6 +70,7 @@ internal class OnboardingNoteCreateWalletModel @Inject constructor(
|
|||
analyticsEventHandler.send(
|
||||
event = OnboardingEvent.CreateWallet.WalletCreatedSuccessfully(
|
||||
passPhraseState = AnalyticsParam.EmptyFull.Empty,
|
||||
referralId = appsFlyerStore.get()?.refcode,
|
||||
),
|
||||
)
|
||||
createWalletAndNavigateBackWithDone(scanResponse.copy(card = result.data.card))
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import com.tangem.core.decompose.model.ParamsContainer
|
|||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.toWrappedList
|
||||
import com.tangem.datasource.local.appsflyer.AppsFlyerStore
|
||||
import com.tangem.datasource.local.config.issuers.IssuersConfigStorage
|
||||
import com.tangem.domain.card.common.TwinCardNumber
|
||||
import com.tangem.domain.card.common.getTwinCardNumber
|
||||
|
|
@ -63,6 +64,7 @@ internal class OnboardingTwinModel @Inject constructor(
|
|||
private val cardRepository: CardRepository,
|
||||
private val uiMessageSender: UiMessageSender,
|
||||
private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase,
|
||||
private val appsFlyerStore: AppsFlyerStore,
|
||||
) : Model() {
|
||||
|
||||
private val params = paramsContainer.require<OnboardingTwinComponent.Params>()
|
||||
|
|
@ -174,6 +176,7 @@ internal class OnboardingTwinModel @Inject constructor(
|
|||
analyticsEventHandler.send(
|
||||
event = OnboardingEvent.CreateWallet.WalletCreatedSuccessfully(
|
||||
passPhraseState = AnalyticsParam.EmptyFull.Empty,
|
||||
referralId = appsFlyerStore.get()?.refcode,
|
||||
),
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ dependencies {
|
|||
implementation(projects.core.analytics)
|
||||
implementation(projects.core.analytics.models)
|
||||
implementation(projects.core.configToggles)
|
||||
implementation(projects.core.datasource)
|
||||
implementation(projects.core.navigation)
|
||||
implementation(projects.core.utils)
|
||||
implementation(projects.core.ui)
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import com.tangem.core.analytics.models.AnalyticsParam.Key.RECEIVE_TOKEN
|
|||
import com.tangem.core.analytics.models.AnalyticsParam.Key.SEND_TOKEN
|
||||
import com.tangem.core.analytics.models.AnalyticsParam.Key.TOKEN_PARAM
|
||||
import com.tangem.core.analytics.models.AppsFlyerIncludedEvent
|
||||
import com.tangem.core.analytics.models.getReferralParams
|
||||
import com.tangem.feature.swap.domain.models.domain.SwapProvider
|
||||
import com.tangem.feature.swap.domain.models.ui.FeeType
|
||||
|
||||
|
|
@ -98,6 +99,7 @@ sealed class SwapEvents(
|
|||
val feeToken: String,
|
||||
val fromDerivationIndex: Int?,
|
||||
val toDerivationIndex: Int?,
|
||||
val referralId: String?,
|
||||
) : SwapEvents(
|
||||
event = "Swap in Progress Screen Opened",
|
||||
params = buildMap {
|
||||
|
|
@ -110,6 +112,7 @@ sealed class SwapEvents(
|
|||
if (fromDerivationIndex != null) put(ACCOUNT_DERIVATION_FROM, fromDerivationIndex.toString())
|
||||
if (toDerivationIndex != null) put(ACCOUNT_DERIVATION_TO, toDerivationIndex.toString())
|
||||
put(FEE_TOKEN, feeToken)
|
||||
putAll(getReferralParams(referralId))
|
||||
},
|
||||
), AppsFlyerIncludedEvent
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import com.tangem.core.navigation.url.UrlOpener
|
|||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.utils.InputNumberFormatter
|
||||
import com.tangem.datasource.local.appsflyer.AppsFlyerStore
|
||||
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
|
||||
import com.tangem.domain.account.status.model.AccountCryptoCurrencyStatus
|
||||
import com.tangem.domain.account.status.usecase.GetAccountCurrencyStatusUseCase
|
||||
|
|
@ -158,6 +159,7 @@ internal class SwapModel @Inject constructor(
|
|||
private val excludedBlockchains: ExcludedBlockchains,
|
||||
private val getUserWalletsUseCase: GetWalletsUseCase,
|
||||
private val getTangemPayCustomerIdUseCase: GetTangemPayCustomerIdUseCase,
|
||||
private val appsFlyerStore: AppsFlyerStore,
|
||||
) : Model() {
|
||||
|
||||
private val params = paramsContainer.require<SwapComponent.Params>()
|
||||
|
|
@ -1108,7 +1110,7 @@ internal class SwapModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun sendSuccessEvent() {
|
||||
private suspend fun sendSuccessEvent() {
|
||||
val provider = dataState.selectedProvider ?: return
|
||||
val fee = (getSelectedFee() as? TxFee.Legacy)?.feeType ?: FeeType.NORMAL
|
||||
val fromCurrency = dataState.fromCryptoCurrency?.currency ?: return
|
||||
|
|
@ -1127,6 +1129,7 @@ internal class SwapModel @Inject constructor(
|
|||
feeToken = getFeeToken().symbol,
|
||||
fromDerivationIndex = fromDerivationIndex,
|
||||
toDerivationIndex = toDerivationIndex,
|
||||
referralId = appsFlyerStore.get()?.refcode,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import com.tangem.core.analytics.models.event.MainScreenAnalyticsEvent
|
|||
import com.tangem.core.analytics.utils.TrackingContextProxy
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.datasource.local.appsflyer.AppsFlyerStore
|
||||
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
|
||||
import com.tangem.domain.account.supplier.SingleAccountListSupplier
|
||||
import com.tangem.domain.account.usecase.IsAccountsModeEnabledUseCase
|
||||
|
|
@ -104,6 +105,7 @@ internal class WalletModel @Inject constructor(
|
|||
private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase,
|
||||
private val feedFeatureToggle: FeedFeatureToggle,
|
||||
private val bindRefcodeWithWalletUseCase: BindRefcodeWithWalletUseCase,
|
||||
private val appsFlyerStore: AppsFlyerStore,
|
||||
val screenLifecycleProvider: ScreenLifecycleProvider,
|
||||
val innerWalletRouter: InnerWalletRouter,
|
||||
) : Model() {
|
||||
|
|
@ -234,6 +236,7 @@ internal class WalletModel @Inject constructor(
|
|||
accountsCount = accountsCount,
|
||||
theme = theme.value,
|
||||
isImported = selectedWallet.isImported(),
|
||||
referralId = appsFlyerStore.get()?.refcode,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,6 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.analytics
|
||||
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.AnalyticsParam
|
||||
import com.tangem.core.analytics.models.AppsFlyerIncludedEvent
|
||||
import com.tangem.core.analytics.models.OneTimeAnalyticsEvent
|
||||
import com.tangem.core.analytics.models.*
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
|
||||
sealed class WalletScreenAnalyticsEvent {
|
||||
|
|
@ -59,6 +56,7 @@ sealed class WalletScreenAnalyticsEvent {
|
|||
private val accountsCount: Int?,
|
||||
val theme: String,
|
||||
val isImported: Boolean,
|
||||
val referralId: String?,
|
||||
) : MainScreen(
|
||||
event = "Screen opened",
|
||||
params = buildMap {
|
||||
|
|
@ -71,6 +69,7 @@ sealed class WalletScreenAnalyticsEvent {
|
|||
"Seedless"
|
||||
}
|
||||
put("Wallet Type", seedPhrase)
|
||||
putAll(getReferralParams(referralId))
|
||||
},
|
||||
), AppsFlyerIncludedEvent
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import com.tangem.core.analytics.models.AnalyticsParam.Key.BLOCKCHAIN
|
|||
import com.tangem.core.analytics.models.AnalyticsParam.Key.ERROR_DESCRIPTION
|
||||
import com.tangem.core.analytics.models.AnalyticsParam.Key.TOKEN_PARAM
|
||||
import com.tangem.core.analytics.models.AppsFlyerIncludedEvent
|
||||
import com.tangem.core.analytics.models.getReferralParams
|
||||
|
||||
sealed class YieldSupplyAnalytics(
|
||||
event: String,
|
||||
|
|
@ -103,22 +104,26 @@ sealed class YieldSupplyAnalytics(
|
|||
data class FundsEarned(
|
||||
val token: String,
|
||||
val blockchain: String,
|
||||
val referralId: String?,
|
||||
) : YieldSupplyAnalytics(
|
||||
event = "Funds Earned",
|
||||
params = mapOf(
|
||||
TOKEN_PARAM to token,
|
||||
BLOCKCHAIN to blockchain,
|
||||
*getReferralParams(referralId).toTypedArray(),
|
||||
),
|
||||
), AppsFlyerIncludedEvent
|
||||
|
||||
data class FundsWithdrawn(
|
||||
val token: String,
|
||||
val blockchain: String,
|
||||
val referralId: String?,
|
||||
) : YieldSupplyAnalytics(
|
||||
event = "Funds Withdrawn",
|
||||
params = mapOf(
|
||||
TOKEN_PARAM to token,
|
||||
BLOCKCHAIN to blockchain,
|
||||
*getReferralParams(referralId).toTypedArray(),
|
||||
),
|
||||
), AppsFlyerIncludedEvent
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ dependencies {
|
|||
|
||||
/** Core */
|
||||
implementation(projects.core.configToggles)
|
||||
implementation(projects.core.datasource)
|
||||
implementation(projects.core.decompose)
|
||||
implementation(projects.core.ui)
|
||||
implementation(projects.core.navigation)
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import com.tangem.core.decompose.model.ParamsContainer
|
|||
import com.tangem.core.ui.components.currency.icon.converter.CryptoCurrencyToIconStateConverter
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.wrappedList
|
||||
import com.tangem.datasource.local.appsflyer.AppsFlyerStore
|
||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
|
|
@ -67,6 +68,7 @@ internal class YieldSupplyStartEarningModel @Inject constructor(
|
|||
private val yieldSupplyGetCurrentFeeUseCase: YieldSupplyGetCurrentFeeUseCase,
|
||||
private val yieldSupplyRepository: YieldSupplyRepository,
|
||||
private val yieldSupplyPendingTracker: YieldSupplyPendingTracker,
|
||||
private val appsFlyerStore: AppsFlyerStore,
|
||||
) : Model(), YieldSupplyNotificationsComponent.ModelCallback {
|
||||
|
||||
private val params: YieldSupplyStartEarningComponent.Params = paramsContainer.require()
|
||||
|
|
@ -274,6 +276,7 @@ internal class YieldSupplyStartEarningModel @Inject constructor(
|
|||
YieldSupplyAnalytics.FundsEarned(
|
||||
blockchain = cryptoCurrency.network.name,
|
||||
token = cryptoCurrency.symbol,
|
||||
referralId = appsFlyerStore.get()?.refcode,
|
||||
),
|
||||
)
|
||||
yieldSupplyFeeUM.transactionDataList.forEach {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import com.tangem.core.navigation.url.UrlOpener
|
|||
import com.tangem.core.ui.components.currency.icon.converter.CryptoCurrencyToIconStateConverter
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.wrappedList
|
||||
import com.tangem.datasource.local.appsflyer.AppsFlyerStore
|
||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
|
|
@ -64,6 +65,7 @@ internal class YieldSupplyStopEarningModel @Inject constructor(
|
|||
private val yieldSupplyDeactivateUseCase: YieldSupplyDeactivateUseCase,
|
||||
private val yieldSupplyRepository: YieldSupplyRepository,
|
||||
private val yieldSupplyPendingTracker: YieldSupplyPendingTracker,
|
||||
private val appsFlyerStore: AppsFlyerStore,
|
||||
) : Model(), YieldSupplyNotificationsComponent.ModelCallback {
|
||||
|
||||
private val params: YieldSupplyStopEarningComponent.Params = paramsContainer.require()
|
||||
|
|
@ -164,7 +166,7 @@ internal class YieldSupplyStopEarningModel @Inject constructor(
|
|||
yieldSupplyAlertFactory.onFailedTxEmailClick(
|
||||
userWallet = params.userWallet,
|
||||
cryptoCurrency = cryptoCurrency,
|
||||
errorMessage = error.toString(),
|
||||
errorMessage = errorMessage,
|
||||
)
|
||||
}
|
||||
},
|
||||
|
|
@ -188,6 +190,7 @@ internal class YieldSupplyStopEarningModel @Inject constructor(
|
|||
YieldSupplyAnalytics.FundsWithdrawn(
|
||||
token = cryptoCurrency.symbol,
|
||||
blockchain = cryptoCurrency.network.name,
|
||||
referralId = appsFlyerStore.get()?.refcode,
|
||||
),
|
||||
)
|
||||
val event = AnalyticsParam.TxSentFrom.Earning(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue