diff --git a/app/src/main/java/com/tangem/App.kt b/app/src/main/java/com/tangem/App.kt index 11f6582f24..b5a4451cb7 100644 --- a/app/src/main/java/com/tangem/App.kt +++ b/app/src/main/java/com/tangem/App.kt @@ -2,6 +2,8 @@ package com.tangem import android.app.Application import androidx.appcompat.app.AppCompatDelegate +import com.google.firebase.analytics.FirebaseAnalytics +import com.google.firebase.crashlytics.FirebaseCrashlytics import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.tangem.data.dp.PrefsManager @@ -14,6 +16,7 @@ import com.tangem.server_android.data.LocalStorage import com.tangem.tangem_card.data.Issuer import com.tangem.tangem_sdk.android.data.Firmwares import com.tangem.tangem_sdk.android.data.PINStorage +import com.tangem.util.Analytics import com.tangem.wallet.BuildConfig import java.io.InputStreamReader import java.nio.charset.StandardCharsets @@ -76,6 +79,9 @@ class App : Application() { } ) } + + FirebaseAnalytics.getInstance(this).setAnalyticsCollectionEnabled(Analytics.isEnabled()) + FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(Analytics.isEnabled()) } private fun buildToastHelperComponent(): ToastHelperComponent { diff --git a/app/src/main/java/com/tangem/data/dp/PrefsManager.kt b/app/src/main/java/com/tangem/data/dp/PrefsManager.kt index b616aa5435..598c719e2b 100644 --- a/app/src/main/java/com/tangem/data/dp/PrefsManager.kt +++ b/app/src/main/java/com/tangem/data/dp/PrefsManager.kt @@ -3,6 +3,7 @@ package com.tangem.data.dp import android.annotation.SuppressLint import android.content.Context import android.content.SharedPreferences +import androidx.preference.PreferenceManager import com.orhanobut.hawk.Hawk import com.tangem.Constant import com.tangem.tangem_card.reader.CardCrypto @@ -10,6 +11,7 @@ import com.tangem.tangem_card.reader.CardCrypto class PrefsManager { companion object { const val PREF_NAME = "tangem_access" + @SuppressLint("StaticFieldLeak") private var instance: PrefsManager? = null @@ -41,6 +43,11 @@ class PrefsManager { Hawk.delete(Constant.PREF_LAST_WALLET_ADDRESS) } + fun getSettingsBoolean(key: Int, default: Boolean): Boolean { + return PreferenceManager.getDefaultSharedPreferences(context) + .getBoolean(context.getString(key), default) + } + fun appendCid(newCid: String) { val prevCids: String = Hawk.get("CID_Key", "") if (!prevCids.contains(newCid)) Hawk.put("CID_Key", "$prevCids$newCid, ") diff --git a/app/src/main/java/com/tangem/ui/fragment/MainFragment.kt b/app/src/main/java/com/tangem/ui/fragment/MainFragment.kt index a594c110a8..b8a9ddf427 100644 --- a/app/src/main/java/com/tangem/ui/fragment/MainFragment.kt +++ b/app/src/main/java/com/tangem/ui/fragment/MainFragment.kt @@ -20,6 +20,8 @@ import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.core.os.bundleOf import androidx.lifecycle.ViewModelProviders +import com.google.firebase.analytics.FirebaseAnalytics +import com.google.firebase.crashlytics.FirebaseCrashlytics import com.tangem.App import com.tangem.Constant import com.tangem.data.Blockchain @@ -46,9 +48,7 @@ import com.tangem.ui.dialog.NoExtendedLengthSupportDialog import com.tangem.ui.dialog.WaitSecurityDelayDialog import com.tangem.ui.fragment.pin.PinRequestFragment import com.tangem.ui.navigation.NavigationResultListener -import com.tangem.util.CommonUtil -import com.tangem.util.LOG -import com.tangem.util.UtilHelper +import com.tangem.util.* import com.tangem.util.extensions.colorFrom import com.tangem.wallet.BuildConfig import com.tangem.wallet.CoinEngineFactory @@ -117,6 +117,9 @@ class MainFragment : BaseFragment(), NavigationResultListener, NfcAdapter.Reader setCardStoreLink() + + FirebaseAnalytics.getInstance(requireActivity()) + .logEvent(AnalyticsEvent.READY_TO_SCAN.event, bundleOf()) } private fun setCardStoreLink() { @@ -270,6 +273,9 @@ class MainFragment : BaseFragment(), NavigationResultListener, NfcAdapter.Reader val ctx = TangemContext(card) + FirebaseAnalytics.getInstance(requireActivity()) + .logEvent(AnalyticsEvent.CARD_IS_SCANNED.event, Analytics.setCardData(ctx)) + when { card.status == TangemCard.Status.Loaded -> lastTag?.let { val engineCoin = CoinEngineFactory.create(ctx) @@ -315,6 +321,7 @@ class MainFragment : BaseFragment(), NavigationResultListener, NfcAdapter.Reader } } else { + FirebaseCrashlytics.getInstance().recordException(cardProtocol.error) // remove last UIDs because of error and no card read rlProgressBar.post { context?.let { Toast.makeText(it, R.string.general_notification_scan_again, Toast.LENGTH_SHORT).show() } diff --git a/app/src/main/java/com/tangem/ui/fragment/PurgeFragment.kt b/app/src/main/java/com/tangem/ui/fragment/PurgeFragment.kt index dc12ed4860..76d8d97dc6 100644 --- a/app/src/main/java/com/tangem/ui/fragment/PurgeFragment.kt +++ b/app/src/main/java/com/tangem/ui/fragment/PurgeFragment.kt @@ -12,6 +12,7 @@ import android.os.Bundle import android.view.View import android.widget.Toast import androidx.core.os.bundleOf +import com.google.firebase.crashlytics.FirebaseCrashlytics import com.tangem.App import com.tangem.Constant import com.tangem.tangem_card.reader.CardProtocol @@ -151,6 +152,7 @@ class PurgeFragment : BaseFragment(), NfcAdapter.ReaderCallback, CardProtocol.No navigateToDestination(R.id.action_purgeFragment_to_mainFragment) } } else { + FirebaseCrashlytics.getInstance().recordException(cardProtocol.error) if (cardProtocol.error is CardProtocol.TangemException_InvalidPIN) { progressBar?.post { progressBar?.progress = 100 diff --git a/app/src/main/java/com/tangem/ui/fragment/SendTransactionFragment.kt b/app/src/main/java/com/tangem/ui/fragment/SendTransactionFragment.kt index 7d709ee662..4e9de2f02e 100644 --- a/app/src/main/java/com/tangem/ui/fragment/SendTransactionFragment.kt +++ b/app/src/main/java/com/tangem/ui/fragment/SendTransactionFragment.kt @@ -6,11 +6,15 @@ import android.nfc.Tag import android.os.Bundle import android.widget.Toast import androidx.activity.OnBackPressedCallback +import androidx.core.os.bundleOf +import com.google.firebase.analytics.FirebaseAnalytics import com.tangem.App import com.tangem.Constant import com.tangem.tangem_card.util.Util import com.tangem.ui.activity.MainActivity import com.tangem.ui.event.TransactionFinishWithSuccess +import com.tangem.util.AnalyticsEvent +import com.tangem.util.AnalyticsParam import com.tangem.util.UtilHelper import com.tangem.wallet.CoinEngine import com.tangem.wallet.CoinEngineFactory @@ -40,7 +44,7 @@ class SendTransactionFragment : BaseFragment(), NfcAdapter.ReaderCallback { if (success) { App.pendingTransactionsStorage.putTransaction(ctx.card, Util.bytesToHex(tx), engine.pendingTransactionTimeoutInSeconds()) finishWithSuccess() - }else + } else finishWithError(ctx.error) } @@ -72,6 +76,11 @@ class SendTransactionFragment : BaseFragment(), NfcAdapter.ReaderCallback { } private fun finishWithSuccess() { + activity?.let { + val params = bundleOf(AnalyticsParam.BLOCKCHAIN.param to ctx.blockchainName) + FirebaseAnalytics.getInstance(it).logEvent(AnalyticsEvent.TRANSACTION_IS_SENT.event, params) + } + val transactionFinishWithSuccess = TransactionFinishWithSuccess() EventBus.getDefault().post(transactionFinishWithSuccess) diff --git a/app/src/main/java/com/tangem/ui/fragment/SettingsFragment.kt b/app/src/main/java/com/tangem/ui/fragment/SettingsFragment.kt index 52fa224f03..98b57d7910 100644 --- a/app/src/main/java/com/tangem/ui/fragment/SettingsFragment.kt +++ b/app/src/main/java/com/tangem/ui/fragment/SettingsFragment.kt @@ -1,18 +1,24 @@ package com.tangem.ui.fragment +import android.content.SharedPreferences import android.os.Bundle import android.view.View import androidx.appcompat.app.AppCompatActivity +import androidx.core.os.bundleOf import androidx.navigation.fragment.NavHostFragment import androidx.preference.ListPreference import androidx.preference.Preference import androidx.preference.PreferenceCategory import androidx.preference.PreferenceFragmentCompat +import com.google.firebase.analytics.FirebaseAnalytics +import com.google.firebase.crashlytics.FirebaseCrashlytics +import com.tangem.util.Analytics +import com.tangem.util.AnalyticsEvent import com.tangem.wallet.BuildConfig import com.tangem.wallet.R import kotlinx.android.synthetic.main.fragment_settings.* -class SettingsFragment : PreferenceFragmentCompat() { +class SettingsFragment : PreferenceFragmentCompat(), SharedPreferences.OnSharedPreferenceChangeListener { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { addPreferencesFromResource(R.xml.pref_main) @@ -40,6 +46,32 @@ class SettingsFragment : PreferenceFragmentCompat() { } } + override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) { + if (key == getString(R.string.pref_analytics)) { + activity?.let { + val analytics = FirebaseAnalytics.getInstance(it) + if (!Analytics.isEnabled()) { + analytics.logEvent(AnalyticsEvent.ANALYTICS_TURNED_OFF.event, bundleOf()) + } + analytics.setAnalyticsCollectionEnabled(Analytics.isEnabled()) + } + FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(Analytics.isEnabled()) + + } + } + + override fun onResume() { + super.onResume() + preferenceScreen.sharedPreferences + .registerOnSharedPreferenceChangeListener(this); + } + + override fun onPause() { + super.onPause() + preferenceScreen.sharedPreferences + .unregisterOnSharedPreferenceChangeListener(this); + } + override fun onDestroyView() { (activity as AppCompatActivity).setSupportActionBar(toolbar) super.onDestroyView() diff --git a/app/src/main/java/com/tangem/ui/fragment/VerifyCardFragment.kt b/app/src/main/java/com/tangem/ui/fragment/VerifyCardFragment.kt index 421f780cc1..1272905501 100644 --- a/app/src/main/java/com/tangem/ui/fragment/VerifyCardFragment.kt +++ b/app/src/main/java/com/tangem/ui/fragment/VerifyCardFragment.kt @@ -69,6 +69,11 @@ class VerifyCardFragment : BaseFragment(), NavigationResultListener, NfcAdapter. super.onViewCreated(view, savedInstanceState) updateViews() + val card = ctx.card + if (!card.allowSwapPIN() && !card.allowSwapPIN2() && card.forbidPurgeWallet()) { + fabMenu.hide() + } + // set listeners fabMenu.setOnClickListener { showMenu(fabMenu) } @@ -278,11 +283,6 @@ class VerifyCardFragment : BaseFragment(), NavigationResultListener, NfcAdapter. ivBlockchain.setImageResource(Blockchain.getLogoImageResource(ctx.card!!.blockchainID, ctx.card!!.tokenSymbol)) - if (ctx.card!!.isReusable!!) - tvReusable.setText(R.string.details_reusable) - else - tvReusable.setText(R.string.details_one_off_card) - var s = "" for (signingM in ctx.card!!.allowedSigningMethod) { s += if (signingM == ctx.card!!.signingMethod) { @@ -328,44 +328,6 @@ class VerifyCardFragment : BaseFragment(), NavigationResultListener, NfcAdapter. tvFirmware.text = ctx.card!!.firmwareVersion - var features = "" - - features += if (ctx.card!!.allowSwapPIN()!! && ctx.card!!.allowSwapPIN2()!!) { - getString(R.string.details_both_pins_can_be_changed) - } else if (ctx.card!!.allowSwapPIN()!!) { - getString(R.string.details_pin1_can_be_changed) - } else if (ctx.card!!.allowSwapPIN2()!!) { - getString(R.string.details_pin2_can_be_changed) - } else { - getString(R.string.details_both_pins_fixed) - } - - if (ctx.card!!.needCVC()!!) - features += getString(R.string.details_required_cvc) - - - if (ctx.card!!.supportDynamicNDEF()!!) { - features += getString(R.string.details_dynamic_ndef) - } else if (ctx.card!!.supportNDEF()!!) - features += getString(R.string.details_ndef) - - if (ctx.card!!.supportBlock()!!) - features += getString(R.string.details_blockable) - - if (ctx.card!!.supportLinkingTerminal()) { - features += getString(R.string.details_linking_card_supported) - llLinkedCard.visibility = View.VISIBLE - } - - - if (ctx.card!!.supportOnlyOneCommandAtTime()) - features += getString(R.string.details_atomic_commmands) - - if (features.endsWith("\n")) - features = features.substring(0, features.length - 1) - - tvFeatures.text = features - val textIsLinked = if (ctx.card.terminalIsLinked) { getString(R.string.details_linked_card_to_phone) } else { @@ -373,25 +335,6 @@ class VerifyCardFragment : BaseFragment(), NavigationResultListener, NfcAdapter. } tvIsLinked.text = textIsLinked - if (ctx.card!!.useDefaultPIN1()) { - imgPIN.setImageResource(R.drawable.unlock_pin1) - imgPIN.setOnClickListener { Toast.makeText(context, R.string.details_protected_by_default_pin_1, Toast.LENGTH_LONG).show() } - } else { - imgPIN.setImageResource(R.drawable.lock_pin1) - imgPIN.setOnClickListener { Toast.makeText(context, R.string.details_protected_by_user_pin_1, Toast.LENGTH_LONG).show() } - } - - if (ctx.card!!.pauseBeforePIN2 > 0 && (ctx.card!!.useDefaultPIN2()!! || !ctx.card!!.useSmartSecurityDelay())) { - imgPIN2orSecurityDelay.setImageResource(R.drawable.timer) - imgPIN2orSecurityDelay.setOnClickListener { Toast.makeText(context, String.format(getString(R.string.details_security_delay), ctx.card!!.pauseBeforePIN2 / 1000.0), Toast.LENGTH_LONG).show() } - } else if (ctx.card!!.useDefaultPIN2()!!) { - imgPIN2orSecurityDelay.setImageResource(R.drawable.unlock_pin2) - imgPIN2orSecurityDelay.setOnClickListener { Toast.makeText(context, R.string.details_protected_by_default_pin_2, Toast.LENGTH_LONG).show() } - } else { - imgPIN2orSecurityDelay.setImageResource(R.drawable.lock_pin2) - imgPIN2orSecurityDelay.setOnClickListener { Toast.makeText(context, R.string.details_protected_by_user_pin_2, Toast.LENGTH_LONG).show() } - } - if (ctx.card!!.useDevelopersFirmware()!!) { imgDeveloperVersion.setImageResource(R.drawable.ic_developer_version) imgDeveloperVersion.visibility = View.VISIBLE diff --git a/app/src/main/java/com/tangem/ui/fragment/id/IdFragment.kt b/app/src/main/java/com/tangem/ui/fragment/id/IdFragment.kt index 7c8ec384e4..8013e66fed 100644 --- a/app/src/main/java/com/tangem/ui/fragment/id/IdFragment.kt +++ b/app/src/main/java/com/tangem/ui/fragment/id/IdFragment.kt @@ -12,6 +12,7 @@ import android.view.View import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat +import com.google.firebase.crashlytics.FirebaseCrashlytics import com.tangem.App import com.tangem.Constant import com.tangem.data.Blockchain @@ -26,7 +27,6 @@ import com.tangem.ui.activity.MainActivity import com.tangem.ui.dialog.NoExtendedLengthSupportDialog import com.tangem.ui.dialog.WaitSecurityDelayDialog import com.tangem.ui.fragment.BaseFragment -import com.tangem.ui.fragment.wallet.LoadedWalletViewModel import com.tangem.util.LOG import com.tangem.util.UtilHelper import com.tangem.wallet.* @@ -232,6 +232,7 @@ class IdFragment : BaseFragment(), NfcAdapter.ReaderCallback, } } else { // remove last UIDs because of error and no card read + FirebaseCrashlytics.getInstance().recordException(cardProtocol.error) rlProgressBar?.post { lastReadSuccess = false if (cardProtocol.error is CardProtocol.TangemException_ExtendedLengthNotSupported) diff --git a/app/src/main/java/com/tangem/ui/fragment/id/ValidateIdFragment.kt b/app/src/main/java/com/tangem/ui/fragment/id/ValidateIdFragment.kt index 04812351c0..2eed027cf3 100644 --- a/app/src/main/java/com/tangem/ui/fragment/id/ValidateIdFragment.kt +++ b/app/src/main/java/com/tangem/ui/fragment/id/ValidateIdFragment.kt @@ -11,12 +11,12 @@ import android.os.Bundle import android.view.View import android.widget.Toast import androidx.activity.OnBackPressedCallback +import com.google.firebase.crashlytics.FirebaseCrashlytics import com.tangem.App import com.tangem.Constant import com.tangem.tangem_card.data.TangemCard import com.tangem.tangem_card.reader.CardProtocol import com.tangem.tangem_card.tasks.OneTouchSignTask -import com.tangem.tangem_card.tasks.SignTask import com.tangem.tangem_card.util.Util import com.tangem.tangem_sdk.android.data.PINStorage import com.tangem.tangem_sdk.android.nfc.NfcDeviceAntennaLocation @@ -24,7 +24,6 @@ import com.tangem.tangem_sdk.android.reader.NfcReader import com.tangem.tangem_sdk.data.EXTRA_TANGEM_CARD import com.tangem.tangem_sdk.data.EXTRA_TANGEM_CARD_UID import com.tangem.tangem_sdk.data.asBundle -import com.tangem.ui.SignTransactionFragment import com.tangem.ui.activity.MainActivity import com.tangem.ui.dialog.NoExtendedLengthSupportDialog import com.tangem.ui.dialog.WaitSecurityDelayDialog @@ -223,6 +222,7 @@ class ValidateIdFragment : BaseFragment(), NavigationResultListener, mpFinishSignSound.start() } else { + FirebaseCrashlytics.getInstance().recordException(cardProtocol.error) lastReadSuccess = false if (cardProtocol.error.javaClass == CardProtocol.TangemException_InvalidPIN::class.java) { progressBar?.post { diff --git a/app/src/main/java/com/tangem/ui/fragment/id/WriteIdFragment.kt b/app/src/main/java/com/tangem/ui/fragment/id/WriteIdFragment.kt index 5b0235f356..3df0850220 100644 --- a/app/src/main/java/com/tangem/ui/fragment/id/WriteIdFragment.kt +++ b/app/src/main/java/com/tangem/ui/fragment/id/WriteIdFragment.kt @@ -11,6 +11,7 @@ import android.os.Bundle import android.view.View import android.widget.Toast import androidx.activity.OnBackPressedCallback +import com.google.firebase.crashlytics.FirebaseCrashlytics import com.tangem.App import com.tangem.Constant import com.tangem.tangem_card.reader.CardProtocol @@ -190,6 +191,7 @@ class WriteIdFragment : BaseFragment(), NavigationResultListener, } else { lastReadSuccess = false + FirebaseCrashlytics.getInstance().recordException(cardProtocol.error) if (cardProtocol.error.javaClass == CardProtocol.TangemException_InvalidPIN::class.java) { progressBar?.post { progressBar?.progress = 100 diff --git a/app/src/main/java/com/tangem/ui/fragment/pin/PinSwapFragment.kt b/app/src/main/java/com/tangem/ui/fragment/pin/PinSwapFragment.kt index 04b12813ba..ee846c13ca 100644 --- a/app/src/main/java/com/tangem/ui/fragment/pin/PinSwapFragment.kt +++ b/app/src/main/java/com/tangem/ui/fragment/pin/PinSwapFragment.kt @@ -10,6 +10,7 @@ import android.os.Bundle import android.view.View import android.widget.ProgressBar import android.widget.Toast +import com.google.firebase.crashlytics.FirebaseCrashlytics import com.tangem.App import com.tangem.Constant import com.tangem.tangem_card.data.TangemCard @@ -112,6 +113,7 @@ class PinSwapFragment : BaseFragment(), NfcAdapter.ReaderCallback, CardProtocol. swapPinTask = null if (cardProtocol != null) { + cardProtocol.error?.let { FirebaseCrashlytics.getInstance().recordException(it) } when { cardProtocol.error == null -> progressBar!!.post { progressBar!!.progress = 100 diff --git a/app/src/main/java/com/tangem/ui/fragment/wallet/CreateNewWalletFragment.kt b/app/src/main/java/com/tangem/ui/fragment/wallet/CreateNewWalletFragment.kt index 5496044e70..51e9ef4544 100644 --- a/app/src/main/java/com/tangem/ui/fragment/wallet/CreateNewWalletFragment.kt +++ b/app/src/main/java/com/tangem/ui/fragment/wallet/CreateNewWalletFragment.kt @@ -9,6 +9,7 @@ import android.nfc.tech.IsoDep import android.os.Bundle import android.view.View import android.widget.Toast +import com.google.firebase.crashlytics.FirebaseCrashlytics import com.tangem.App import com.tangem.Constant import com.tangem.tangem_card.reader.CardProtocol @@ -101,6 +102,7 @@ class CreateNewWalletFragment : BaseFragment(), NfcAdapter.ReaderCallback, CardP return@post } } else { + FirebaseCrashlytics.getInstance().recordException(cardProtocol.error) lastReadSuccess = false if (cardProtocol.error is CardProtocol.TangemException_InvalidPIN) { progressBar?.post { diff --git a/app/src/main/java/com/tangem/ui/fragment/wallet/EmptyWalletFragment.kt b/app/src/main/java/com/tangem/ui/fragment/wallet/EmptyWalletFragment.kt index 65461743c6..e8a4cc7542 100644 --- a/app/src/main/java/com/tangem/ui/fragment/wallet/EmptyWalletFragment.kt +++ b/app/src/main/java/com/tangem/ui/fragment/wallet/EmptyWalletFragment.kt @@ -13,6 +13,7 @@ import android.os.Bundle import android.text.Html import android.view.View import android.widget.Toast +import com.google.firebase.crashlytics.FirebaseCrashlytics import com.tangem.App import com.tangem.Constant import com.tangem.tangem_card.data.TangemCard @@ -181,6 +182,7 @@ class EmptyWalletFragment : BaseFragment(), NavigationResultListener, this.cardProtocol = cardProtocol } } else { + FirebaseCrashlytics.getInstance().recordException(cardProtocol.error) // remove last UIDs because of error and no card read progressBar?.post { lastReadSuccess = false diff --git a/app/src/main/java/com/tangem/ui/fragment/wallet/LoadedWalletFragment.kt b/app/src/main/java/com/tangem/ui/fragment/wallet/LoadedWalletFragment.kt index 4de8ee31c8..e1055fbfce 100644 --- a/app/src/main/java/com/tangem/ui/fragment/wallet/LoadedWalletFragment.kt +++ b/app/src/main/java/com/tangem/ui/fragment/wallet/LoadedWalletFragment.kt @@ -337,6 +337,7 @@ class LoadedWalletFragment : BaseFragment(), NavigationResultListener, NfcAdapte @Subscribe fun onTransactionFinishWithSuccess(transactionFinishWithSuccess: TransactionFinishWithSuccess) { refreshAction = Runnable { refresh() } + ctx.card.remainingSignatures -= 1 srl?.postDelayed(refreshAction, 10000) } @@ -478,6 +479,7 @@ class LoadedWalletFragment : BaseFragment(), NavigationResultListener, NfcAdapte Constant.REQUEST_CODE_SEND_TRANSACTION, Constant.REQUEST_CODE_RECEIVE_TRANSACTION -> { if (resultCode == Activity.RESULT_OK) { +// ctx.card.remainingSignatures = ctx.card.remainingSignatures - 1 ctx.coinData?.clearInfo() srl?.postDelayed({ this.refresh() }, 5000) srl?.isRefreshing = true diff --git a/app/src/main/java/com/tangem/util/Analytics.kt b/app/src/main/java/com/tangem/util/Analytics.kt new file mode 100644 index 0000000000..c01d40e340 --- /dev/null +++ b/app/src/main/java/com/tangem/util/Analytics.kt @@ -0,0 +1,39 @@ +package com.tangem.util + +import android.os.Bundle +import androidx.core.os.bundleOf +import com.tangem.data.dp.PrefsManager +import com.tangem.wallet.R +import com.tangem.wallet.TangemContext + +enum class AnalyticsEvent(val event: String) { + CARD_IS_SCANNED("card_is_scanned"), + TRANSACTION_IS_SENT("transaction_is_sent"), + READY_TO_SCAN("ready_to_scan"), + READY_TO_SIGN("ready_to_sign"), + SIGNED("signed"), + ANALYTICS_TURNED_OFF("analytics_turned_off"), + ; +} + +enum class AnalyticsParam(val param: String) { + BLOCKCHAIN("blockchain"), + BATCH_ID("batch_id"), + FIRMWARE("firmware"), + ; +} +class Analytics { + companion object { + fun setCardData(ctx: TangemContext): Bundle { + return bundleOf( + AnalyticsParam.BLOCKCHAIN.param to ctx.blockchainName, + AnalyticsParam.BATCH_ID.param to ctx.card.batch, + AnalyticsParam.FIRMWARE.param to ctx.card.firmwareVersion + ) + } + + fun isEnabled(): Boolean { + return PrefsManager.getInstance().getSettingsBoolean(R.string.pref_analytics, true) + } + } +} diff --git a/app/src/main/java/com/tangem/wallet/TangemContext.java b/app/src/main/java/com/tangem/wallet/TangemContext.java index df164a4616..a027d33f3b 100644 --- a/app/src/main/java/com/tangem/wallet/TangemContext.java +++ b/app/src/main/java/com/tangem/wallet/TangemContext.java @@ -4,10 +4,12 @@ import android.content.Context; import android.content.Intent; import android.os.Bundle; +import com.google.firebase.crashlytics.FirebaseCrashlytics; import com.tangem.Constant; import com.tangem.data.Blockchain; import com.tangem.tangem_card.data.TangemCard; import com.tangem.tangem_sdk.data.TangemCardExtensionsKt; +import com.tangem.util.AnalyticsParam; public class TangemContext { // public static final String EXTRA_BLOCKCHAIN_DATA = "BLOCKCHAIN_DATA"; @@ -58,7 +60,7 @@ public class TangemContext { public String getBlockchainName() { Blockchain blockchain = getBlockchain(); if (blockchain == Blockchain.Token || blockchain == Blockchain.RootstockToken) { - return card.getTokenSymbol()+ "
" + getBlockchain().getOfficialName() + " smart contract token"; + return card.getTokenSymbol() + "
" + getBlockchain().getOfficialName() + " smart contract token"; } if (blockchain == Blockchain.NftToken) { return card.getTokenSymbol().substring(4) + "
" + getBlockchain().getOfficialName() + " non-fungible token"; @@ -67,7 +69,7 @@ public class TangemContext { return card.getTokenSymbol() + "
" + getBlockchain().getOfficialName() + " asset"; } if (blockchain == Blockchain.StellarTag) { - return "TANGEM TAG
"+ getBlockchain().getOfficialName() + " non-fungible token "; + return "TANGEM TAG
" + getBlockchain().getOfficialName() + " non-fungible token "; } return blockchain.getOfficialName(); } @@ -97,6 +99,11 @@ public class TangemContext { } public void setError(String error) { + if (error != null) { + FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance(); + crashlytics.setCustomKey(AnalyticsParam.BLOCKCHAIN.getParam(), getBlockchainName()); + crashlytics.recordException(new Exception(error)); + } this.error = error; } diff --git a/app/src/main/res/layout/fr_verify_card.xml b/app/src/main/res/layout/fr_verify_card.xml index 189186e5f5..cef381db19 100644 --- a/app/src/main/res/layout/fr_verify_card.xml +++ b/app/src/main/res/layout/fr_verify_card.xml @@ -159,32 +159,6 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 39cb7cd948..67cf1e495e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -28,6 +28,7 @@ Settings Common Manual editing Fee + Share anonymous data with developers Encryption modes None @@ -187,6 +188,9 @@ Incorrect destination wallet address Destination wallet address equal source address Amount is empty + Only one signature left + You need to send all available funds in this transaction + target wallet address diff --git a/app/src/main/res/values/strings_untranslatable.xml b/app/src/main/res/values/strings_untranslatable.xml index 0b6a2bcf98..419b1c6812 100644 --- a/app/src/main/res/values/strings_untranslatable.xml +++ b/app/src/main/res/values/strings_untranslatable.xml @@ -26,6 +26,7 @@ category_common manual_editing_fee + analytics select_nodes encryption_modes diff --git a/app/src/main/res/xml/pref_main.xml b/app/src/main/res/xml/pref_main.xml index 47be8c9663..e00d77c325 100644 --- a/app/src/main/res/xml/pref_main.xml +++ b/app/src/main/res/xml/pref_main.xml @@ -4,11 +4,16 @@ android:key="@string/pref_category_common" android:title="@string/settings_category_сommon"> - + + diff --git a/app/src/tangemAccess/java/com/tangem/ui/PrepareTransactionFragment.kt b/app/src/tangemAccess/java/com/tangem/ui/PrepareTransactionFragment.kt index cdea28160d..48a385a3d8 100644 --- a/app/src/tangemAccess/java/com/tangem/ui/PrepareTransactionFragment.kt +++ b/app/src/tangemAccess/java/com/tangem/ui/PrepareTransactionFragment.kt @@ -54,8 +54,18 @@ class PrepareTransactionFragment : BaseFragment(), NavigationResultListener, Nfc rgIncFee.visibility = View.VISIBLE } - if (ctx.card!!.remainingSignatures < 2) + if (ctx.card!!.remainingSignatures < 2) { etAmount.isEnabled = false + } + + if (ctx.card.remainingSignatures == 1) { + androidx.appcompat.app.AlertDialog.Builder(requireContext()) + .setTitle(R.string.prepare_transaction_warning_last_signature) + .setMessage(R.string.prepare_transaction_warning_send_full_amount) + .setPositiveButton(R.string.general_ok) { _, _ -> } + .create() + .show() + } tvCurrency.text = engine.balance.currency etAmount.setText(engine.balance.toValueString()) @@ -144,7 +154,7 @@ class PrepareTransactionFragment : BaseFragment(), NavigationResultListener, Nfc val schemeSplit = code!!.split(":") when (schemeSplit.size) { 2 -> { - if (ctx.blockchain.officialName.toLowerCase(Locale.ROOT).replace("\\s","") == schemeSplit[0]) { + if (ctx.blockchain.officialName.toLowerCase(Locale.ROOT).replace("\\s", "") == schemeSplit[0]) { val uri = Uri.parse(schemeSplit[1]) etWallet?.setText(uri.path) // val amount = uri.getQueryParameter("amount") //TODO: enable after redesign diff --git a/app/src/tangemAccess/java/com/tangem/ui/SignTransactionFragment.kt b/app/src/tangemAccess/java/com/tangem/ui/SignTransactionFragment.kt index 8429ec1e2e..bb5858b8e3 100644 --- a/app/src/tangemAccess/java/com/tangem/ui/SignTransactionFragment.kt +++ b/app/src/tangemAccess/java/com/tangem/ui/SignTransactionFragment.kt @@ -11,6 +11,8 @@ import android.os.Bundle import android.view.View import android.widget.Toast import androidx.activity.OnBackPressedCallback +import com.google.firebase.analytics.FirebaseAnalytics +import com.google.firebase.crashlytics.FirebaseCrashlytics import com.tangem.App import com.tangem.Constant import com.tangem.tangem_card.reader.CardProtocol @@ -26,6 +28,8 @@ import com.tangem.ui.dialog.NoExtendedLengthSupportDialog import com.tangem.ui.dialog.WaitSecurityDelayDialog import com.tangem.ui.fragment.BaseFragment import com.tangem.ui.navigation.NavigationResultListener +import com.tangem.util.Analytics +import com.tangem.util.AnalyticsEvent import com.tangem.util.LOG import com.tangem.wallet.CoinEngine import com.tangem.wallet.CoinEngineFactory @@ -34,7 +38,6 @@ import com.tangem.wallet.TangemContext import kotlinx.android.synthetic.main.layout_progress_horizontal.* import kotlinx.android.synthetic.main.layout_touch_card.* import kotlinx.android.synthetic.tangemAccess.fragment_sign_transaction.* -import java.lang.IllegalArgumentException class SignTransactionFragment : BaseFragment(), NavigationResultListener, @@ -88,6 +91,9 @@ class SignTransactionFragment : BaseFragment(), NavigationResultListener, tvCardID.text = ctx.card!!.cidDescription progressBar.progressTintList = ColorStateList.valueOf(Color.DKGRAY) progressBar.visibility = View.INVISIBLE + + FirebaseAnalytics.getInstance(requireActivity()) + .logEvent(AnalyticsEvent.READY_TO_SIGN.event, Analytics.setCardData(ctx)) } override fun onPause() { @@ -175,6 +181,10 @@ class SignTransactionFragment : BaseFragment(), NavigationResultListener, signTransactionTask = null if (cardProtocol != null) { if (cardProtocol.error == null) { + + FirebaseAnalytics.getInstance(requireActivity()) + .logEvent(AnalyticsEvent.SIGNED.event, Analytics.setCardData(ctx)) + rlProgressBar?.post { rlProgressBar?.visibility = View.GONE } progressBar?.post { @@ -185,6 +195,7 @@ class SignTransactionFragment : BaseFragment(), NavigationResultListener, mpFinishSignSound.start() } else { lastReadSuccess = false + FirebaseCrashlytics.getInstance().recordException(cardProtocol.error) if (cardProtocol.error.javaClass == CardProtocol.TangemException_InvalidPIN::class.java) { progressBar?.post { progressBar?.progress = 100 diff --git a/server-android/src/main/res/drawable/card_tg061.png b/server-android/src/main/res/drawable/card_tg061.png index d836185971..e49f9df65b 100644 Binary files a/server-android/src/main/res/drawable/card_tg061.png and b/server-android/src/main/res/drawable/card_tg061.png differ diff --git a/tangem-card-old/src/main/java/com/tangem/tangem_card/data/TangemCard.java b/tangem-card-old/src/main/java/com/tangem/tangem_card/data/TangemCard.java index 37da532954..7d924574a6 100644 --- a/tangem-card-old/src/main/java/com/tangem/tangem_card/data/TangemCard.java +++ b/tangem-card-old/src/main/java/com/tangem/tangem_card/data/TangemCard.java @@ -8,7 +8,6 @@ import com.tangem.tangem_card.reader.TLVList; import com.tangem.tangem_card.util.Util; import java.nio.charset.StandardCharsets; -import java.util.ArrayList; import java.util.Date; import java.util.EnumSet; @@ -359,6 +358,11 @@ public class TangemCard { return (settingsMask & SettingsMask.AllowSwapPIN2) != 0; } + public Boolean forbidPurgeWallet() { + if (settingsMask == null) return null; + return (settingsMask & SettingsMask.ForbidPurgeWallet) != 0; + } + public Boolean needCVC() { if (settingsMask == null) return null; return (settingsMask & SettingsMask.UseCVC) != 0; diff --git a/tangem-core/src/main/java/com/tangem/common/CardEnvironment.kt b/tangem-core/src/main/java/com/tangem/common/CardEnvironment.kt index c556f427b3..09cfd736b4 100644 --- a/tangem-core/src/main/java/com/tangem/common/CardEnvironment.kt +++ b/tangem-core/src/main/java/com/tangem/common/CardEnvironment.kt @@ -1,5 +1,8 @@ package com.tangem.common +import com.tangem.commands.EllipticCurve +import com.tangem.crypto.CryptoUtils.generatePublicKey + /** * Contains data relating to a Tangem card. It is used in constructing all the commands, @@ -27,4 +30,8 @@ enum class EncryptionMode(val code: Byte) { STRONG(0x2) } -class KeyPair(val publicKey: ByteArray, val privateKey: ByteArray) \ No newline at end of file +class KeyPair(val publicKey: ByteArray, val privateKey: ByteArray) { + + constructor(privateKey: ByteArray, curve: EllipticCurve = EllipticCurve.Secp256k1) : + this(generatePublicKey(privateKey, curve), privateKey) +} \ No newline at end of file diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/domain/actions/DepesonalizeAction.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/domain/actions/DepersonalizeAction.kt similarity index 95% rename from tangem-demo/src/main/java/com/tangem/tangemtest/ucase/domain/actions/DepesonalizeAction.kt rename to tangem-demo/src/main/java/com/tangem/tangemtest/ucase/domain/actions/DepersonalizeAction.kt index 6b17c19205..6a08e2e816 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/domain/actions/DepesonalizeAction.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/domain/actions/DepersonalizeAction.kt @@ -9,7 +9,7 @@ import com.tangem.tangemtest.ucase.variants.TlvId /** [REDACTED_AUTHOR] */ -class DepesonalizeAction : BaseAction() { +class DepersonalizeAction : BaseAction() { override fun executeMainAction(payload: PayloadHolder, attrs: AttrForAction, callback: ActionCallback) { val item = attrs.itemList.findDataItem(TlvId.CardId) ?: return val cardId = item.viewModel.data as? String ?: return diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/domain/paramsManager/managers/DepersonalizeItemsManager.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/domain/paramsManager/managers/DepersonalizeItemsManager.kt index 659b371b4e..8267c86bb6 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/domain/paramsManager/managers/DepersonalizeItemsManager.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/domain/paramsManager/managers/DepersonalizeItemsManager.kt @@ -4,14 +4,14 @@ import com.tangem.CardManager import com.tangem.tangemtest._arch.structure.Id import com.tangem.tangemtest._arch.structure.abstraction.Item import com.tangem.tangemtest._arch.structure.impl.EditTextItem -import com.tangem.tangemtest.ucase.domain.actions.DepesonalizeAction +import com.tangem.tangemtest.ucase.domain.actions.DepersonalizeAction import com.tangem.tangemtest.ucase.domain.paramsManager.ActionCallback import com.tangem.tangemtest.ucase.variants.TlvId /** [REDACTED_AUTHOR] */ -class DepersonalizeItemsManager : BaseItemsManager(DepesonalizeAction()) { +class DepersonalizeItemsManager : BaseItemsManager(DepersonalizeAction()) { override fun createItemsList(): List { return listOf(EditTextItem(TlvId.CardId, null)) } diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/depersonalize/ui/DepesonalizeActionFragment.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/depersonalize/ui/DepersonalizeActionFragment.kt similarity index 85% rename from tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/depersonalize/ui/DepesonalizeActionFragment.kt rename to tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/depersonalize/ui/DepersonalizeActionFragment.kt index 98e0d53ab4..6567e465b1 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/depersonalize/ui/DepesonalizeActionFragment.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/depersonalize/ui/DepersonalizeActionFragment.kt @@ -7,7 +7,7 @@ import com.tangem.tangemtest.ucase.ui.BaseCardActionFragment /** [REDACTED_AUTHOR] */ -class DepesonalizeActionFragment : BaseCardActionFragment() { +class DepersonalizeActionFragment : BaseCardActionFragment() { override fun getLayoutId(): Int = R.layout.fg_depersonalize diff --git a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/converter/ValueMapper.kt b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/converter/ValueMapper.kt index ec62e47839..9063a56fe3 100644 --- a/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/converter/ValueMapper.kt +++ b/tangem-demo/src/main/java/com/tangem/tangemtest/ucase/variants/personalize/converter/ValueMapper.kt @@ -22,7 +22,7 @@ class ValueMapper { default.init(defaultConfig) updatedByItemList.init(defaultConfig) startMapping(itemList) - return createJson(defaultConfig) + return createConfig() } private fun startMapping(itemList: List) { @@ -39,69 +39,68 @@ class ValueMapper { } } - private fun createJson(defaultConfig: PersonalizeConfig): PersonalizeConfig { + private fun createConfig(): PersonalizeConfig { val export = PersonalizeConfig() - export.series = getTyped(CardNumber.Series, defaultConfig.series) - export.startNumber = getTyped(CardNumber.Number, defaultConfig.startNumber) - export.batchId = getTyped(CardNumber.BatchId, defaultConfig.batchId) - export.curveID = getTyped(Common.Curve, defaultConfig.curveID) - export.blockchain = getTyped(Common.Blockchain, defaultConfig.blockchain) - export.blockchainCustom = getTyped(Common.BlockchainCustom, defaultConfig.blockchainCustom) - export.MaxSignatures = getTyped(Common.MaxSignatures, defaultConfig.MaxSignatures) - export.createWallet = getTyped(Common.CreateWallet, defaultConfig.createWallet) - export.SigningMethod0 = getTyped(SigningMethod.SignTx, defaultConfig.SigningMethod0) - export.SigningMethod1 = getTyped(SigningMethod.SignTxRaw, defaultConfig.SigningMethod1) - export.SigningMethod2 = getTyped(SigningMethod.SignValidatedTx, defaultConfig.SigningMethod2) - export.SigningMethod3 = getTyped(SigningMethod.SignValidatedTxRaw, defaultConfig.SigningMethod3) - export.SigningMethod4 = getTyped(SigningMethod.SignValidatedTxIssuer, defaultConfig.SigningMethod4) - export.SigningMethod5 = getTyped(SigningMethod.SignValidatedTxRawIssuer, defaultConfig.SigningMethod5) - export.SigningMethod6 = getTyped(SigningMethod.SignExternal, defaultConfig.SigningMethod6) - export.pinLessFloorLimit = getTyped(SignHashExProp.PinLessFloorLimit, defaultConfig.pinLessFloorLimit) - export.hexCrExKey = getTyped(SignHashExProp.CryptoExKey, defaultConfig.hexCrExKey) - export.requireTerminalCertSignature = getTyped(SignHashExProp.RequireTerminalCertSig, defaultConfig.requireTerminalCertSignature) - export.requireTerminalTxSignature = getTyped(SignHashExProp.RequireTerminalTxSig, defaultConfig.requireTerminalTxSignature) - export.checkPIN3onCard = getTyped(SignHashExProp.CheckPin3, defaultConfig.checkPIN3onCard) - export.writeOnPersonalization = getTyped(Denomination.WriteOnPersonalize, defaultConfig.writeOnPersonalization) - export.denomination = getTyped(Denomination.Denomination, defaultConfig.denomination) - export.itsToken = getTyped(Token.ItsToken, defaultConfig.itsToken) - export.symbol = getTyped(Token.Symbol, defaultConfig.symbol) - export.contractAddress = getTyped(Token.ContractAddress, defaultConfig.contractAddress) - export.decimal = getTyped(Token.Decimal, defaultConfig.decimal) - export.cardData = export.cardData.apply { this.product_note = getTyped(ProductMask.Note, defaultConfig.cardData.product_note) } - export.cardData = export.cardData.apply { this.product_tag = getTyped(ProductMask.Tag, defaultConfig.cardData.product_tag) } - export.cardData = export.cardData.apply { this.product_id_card = getTyped(ProductMask.CardId, defaultConfig.cardData.product_id_card) } - export.isReusable = getTyped(SettingsMask.IsReusable, defaultConfig.isReusable) - export.useActivation = getTyped(SettingsMask.NeedActivation, defaultConfig.useActivation) - export.forbidPurgeWallet = getTyped(SettingsMask.ForbidPurge, defaultConfig.forbidPurgeWallet) - export.allowSelectBlockchain = getTyped(SettingsMask.AllowSelectBlockchain, defaultConfig.allowSelectBlockchain) - export.useBlock = getTyped(SettingsMask.UseBlock, defaultConfig.useBlock) - export.oneApdu = getTyped(SettingsMask.OneApdu, defaultConfig.oneApdu) - export.useCVC = getTyped(SettingsMask.UseCvc, defaultConfig.useCVC) - export.allowSwapPIN = getTyped(SettingsMask.AllowSwapPin, defaultConfig.allowSwapPIN) - export.allowSwapPIN2 = getTyped(SettingsMask.AllowSwapPin2, defaultConfig.allowSwapPIN2) - export.forbidDefaultPIN = getTyped(SettingsMask.ForbidDefaultPin, defaultConfig.forbidDefaultPIN) - export.smartSecurityDelay = getTyped(SettingsMask.SmartSecurityDelay, defaultConfig.smartSecurityDelay) - export.protectIssuerDataAgainstReplay = getTyped(SettingsMask.ProtectIssuerDataAgainstReplay, defaultConfig.protectIssuerDataAgainstReplay) - export.skipSecurityDelayIfValidatedByIssuer = getTyped(SettingsMask.SkipSecurityDelayIfValidated, defaultConfig.skipSecurityDelayIfValidatedByIssuer) - export.skipCheckPIN2andCVCIfValidatedByIssuer = getTyped(SettingsMask.SkipPin2CvcIfValidated, defaultConfig.skipCheckPIN2andCVCIfValidatedByIssuer) - export.skipSecurityDelayIfValidatedByLinkedTerminal = getTyped(SettingsMask.SkipSecurityDelayOnLinkedTerminal, defaultConfig.skipSecurityDelayIfValidatedByLinkedTerminal) - export.restrictOverwriteIssuerDataEx = getTyped(SettingsMask.RestrictOverwriteExtraIssuerData, defaultConfig.restrictOverwriteIssuerDataEx) - export.protocolAllowUnencrypted = getTyped(SettingsMaskProtocolEnc.AllowUnencrypted, defaultConfig.protocolAllowUnencrypted) - export.protocolAllowStaticEncryption = getTyped(SettingsMaskProtocolEnc.AllowStaticEncryption, defaultConfig.protocolAllowStaticEncryption) - export.useNDEF = getTyped(SettingsMaskNdef.UseNdef, defaultConfig.useNDEF) - export.useDynamicNDEF = getTyped(SettingsMaskNdef.DynamicNdef, defaultConfig.useDynamicNDEF) - export.disablePrecomputedNDEF = getTyped(SettingsMaskNdef.DisablePrecomputedNdef, defaultConfig.disablePrecomputedNDEF) - export.aar = getTyped(SettingsMaskNdef.Aar, defaultConfig.aar) - export.aarCustom = getTyped(SettingsMaskNdef.AarCustom, defaultConfig.aarCustom) - export.PIN = getTyped(Pins.Pin, defaultConfig.PIN) - export.PIN2 = getTyped(Pins.Pin2, defaultConfig.PIN2) - export.PIN3 = getTyped(Pins.Pin3, defaultConfig.PIN3) - export.CVC = getTyped(Pins.Cvc, defaultConfig.CVC) - export.pauseBeforePIN2 = getTyped(Pins.PauseBeforePin2, defaultConfig.pauseBeforePIN2) + export.series = getTyped(CardNumber.Series) + export.startNumber = getTyped(CardNumber.Number) + export.curveID = getTyped(Common.Curve) + export.blockchain = getTyped(Common.Blockchain) + export.blockchainCustom = getTyped(Common.BlockchainCustom) + export.MaxSignatures = getTyped(Common.MaxSignatures) + export.createWallet = getTyped(Common.CreateWallet) + export.SigningMethod0 = getTyped(SigningMethod.SignTx) + export.SigningMethod1 = getTyped(SigningMethod.SignTxRaw) + export.SigningMethod2 = getTyped(SigningMethod.SignValidatedTx) + export.SigningMethod3 = getTyped(SigningMethod.SignValidatedTxRaw) + export.SigningMethod4 = getTyped(SigningMethod.SignValidatedTxIssuer) + export.SigningMethod5 = getTyped(SigningMethod.SignValidatedTxRawIssuer) + export.SigningMethod6 = getTyped(SigningMethod.SignExternal) + export.pinLessFloorLimit = getTyped(SignHashExProp.PinLessFloorLimit) + export.hexCrExKey = getTyped(SignHashExProp.CryptoExKey) + export.requireTerminalCertSignature = getTyped(SignHashExProp.RequireTerminalCertSig) + export.requireTerminalTxSignature = getTyped(SignHashExProp.RequireTerminalTxSig) + export.checkPIN3onCard = getTyped(SignHashExProp.CheckPin3) + export.writeOnPersonalization = getTyped(Denomination.WriteOnPersonalize) + export.denomination = getTyped(Denomination.Denomination) + export.itsToken = getTyped(Token.ItsToken) + export.symbol = getTyped(Token.Symbol) + export.contractAddress = getTyped(Token.ContractAddress) + export.decimal = getTyped(Token.Decimal) + export.cardData = export.cardData.apply { this.product_note = getTyped(ProductMask.Note) } + export.cardData = export.cardData.apply { this.product_tag = getTyped(ProductMask.Tag) } + export.cardData = export.cardData.apply { this.product_id_card = getTyped(ProductMask.CardId) } + export.isReusable = getTyped(SettingsMask.IsReusable) + export.useActivation = getTyped(SettingsMask.NeedActivation) + export.forbidPurgeWallet = getTyped(SettingsMask.ForbidPurge) + export.allowSelectBlockchain = getTyped(SettingsMask.AllowSelectBlockchain) + export.useBlock = getTyped(SettingsMask.UseBlock) + export.oneApdu = getTyped(SettingsMask.OneApdu) + export.useCVC = getTyped(SettingsMask.UseCvc) + export.allowSwapPIN = getTyped(SettingsMask.AllowSwapPin) + export.allowSwapPIN2 = getTyped(SettingsMask.AllowSwapPin2) + export.forbidDefaultPIN = getTyped(SettingsMask.ForbidDefaultPin) + export.smartSecurityDelay = getTyped(SettingsMask.SmartSecurityDelay) + export.protectIssuerDataAgainstReplay = getTyped(SettingsMask.ProtectIssuerDataAgainstReplay) + export.skipSecurityDelayIfValidatedByIssuer = getTyped(SettingsMask.SkipSecurityDelayIfValidated) + export.skipCheckPIN2andCVCIfValidatedByIssuer = getTyped(SettingsMask.SkipPin2CvcIfValidated) + export.skipSecurityDelayIfValidatedByLinkedTerminal = getTyped(SettingsMask.SkipSecurityDelayOnLinkedTerminal) + export.restrictOverwriteIssuerDataEx = getTyped(SettingsMask.RestrictOverwriteExtraIssuerData) + export.protocolAllowUnencrypted = getTyped(SettingsMaskProtocolEnc.AllowUnencrypted) + export.allowFastEncryption = getTyped(SettingsMaskProtocolEnc.AlloFastEncryption) + export.useNDEF = getTyped(SettingsMaskNdef.UseNdef) + export.useDynamicNDEF = getTyped(SettingsMaskNdef.DynamicNdef) + export.disablePrecomputedNDEF = getTyped(SettingsMaskNdef.DisablePrecomputedNdef) + export.aar = getTyped(SettingsMaskNdef.Aar) + export.aarCustom = getTyped(SettingsMaskNdef.AarCustom) + export.PIN = getTyped(Pins.Pin) + export.PIN2 = getTyped(Pins.Pin2) + export.PIN3 = getTyped(Pins.Pin3) + export.CVC = getTyped(Pins.Cvc) + export.pauseBeforePIN2 = getTyped(Pins.PauseBeforePin2) return export } - private inline fun getTyped(id: Id, def: Type): Type { + private inline fun getTyped(id: Id): Type { return getTypedBy(updatedByItemList, id) ?: getTypedBy(default, id)!! } diff --git a/tangem-demo/src/main/res/navigation/navigation.xml b/tangem-demo/src/main/res/navigation/navigation.xml index 2c0c71483e..42db9c6d1c 100644 --- a/tangem-demo/src/main/res/navigation/navigation.xml +++ b/tangem-demo/src/main/res/navigation/navigation.xml @@ -69,7 +69,7 @@