diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 1634169316..df6d24b384 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -26,8 +26,11 @@ dependencies {
implementation(project(":domain:models"))
implementation(project(":domain:core"))
implementation(project(":domain:card"))
+ implementation(project(":domain:wallets"))
+ implementation(project(":domain:wallets:models"))
implementation(project(":common"))
implementation(project(":core:analytics"))
+ implementation(project(":core:navigation"))
implementation(project(":core:featuretoggles"))
implementation(project(":core:res"))
implementation(project(":core:ui"))
@@ -39,6 +42,8 @@ dependencies {
/** Features */
implementation(project(":features:onboarding"))
+ implementation(project(":features:learn2earn:api"))
+ implementation(project(":features:learn2earn:impl"))
implementation(project(":features:referral:presentation"))
implementation(project(":features:referral:domain"))
implementation(project(":features:referral:data"))
@@ -50,6 +55,8 @@ dependencies {
implementation(project(":features:tester:impl"))
implementation(project(":features:wallet:api"))
implementation(project(":features:wallet:impl"))
+ implementation(projects.features.tokendetails.api)
+ implementation(projects.features.tokendetails.impl)
/** AndroidX libraries */
implementation(deps.androidx.core.ktx)
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index ef93ea2179..53d4be3c7f 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -36,6 +36,7 @@
android:largeHeap="@bool/largeHeap"
android:networkSecurityConfig="@xml/network_security_config"
android:roundIcon="@mipmap/ic_launcher"
+ android:extractNativeLibs="true"
android:supportsRtl="true"
tools:ignore="GoogleAppIndexingWarning"
tools:replace="android:allowBackup, android:fullBackupContent">
@@ -138,6 +139,10 @@
android:name="com.tangem.tap.features.sprinklr.ui.SprinklrActivity"
android:theme="@style/AppTheme" />
+
+
{
- navigateToInitialScreen(intent)
+ navigateToInitialScreenOnResume(intentWhichStartedActivity)
}
backStackIsEmpty -> {
- navigateToInitialScreen(intent)
+ navigateToInitialScreenOnResume(intentWhichStartedActivity)
}
else -> Unit
}
}
- private fun navigateToInitialScreen(intent: Intent?) {
+ private fun navigateToInitialScreenOnResume(intentWhichStartedActivity: Intent?) {
if (store.state.globalState.userWalletsListManager?.hasUserWallets == true) {
store.dispatchOnMain(NavigationAction.NavigateTo(AppScreen.Welcome))
- store.dispatchOnMain(WelcomeAction.HandleIntentIfNeeded(intent))
+ store.dispatchOnMain(WelcomeAction.SetInitialIntent(intentWhichStartedActivity))
+ scope.launch {
+ val handler = BackgroundScanIntentHandler(hasSavedUserWalletsProvider = { true })
+ val isBackgroundScanNotHandled = handler.handleIntent(intentWhichStartedActivity)
+ val hasNotIncompletedBackup = !backupService.hasIncompletedBackup
+ if (isBackgroundScanNotHandled && hasNotIncompletedBackup) {
+ store.dispatchOnMain(WelcomeAction.ProceedWithBiometrics)
+ }
+ }
} else {
store.dispatchOnMain(NavigationAction.NavigateTo(AppScreen.Home))
- intentHandler.handleIntent(intent, hasSavedUserWallets = false)
+ scope.launch {
+ intentProcessor.handleIntent(intentWhichStartedActivity)
+ }
}
store.dispatch(BackupAction.CheckForUnfinishedBackup)
}
diff --git a/app/src/main/java/com/tangem/tap/TapApplication.kt b/app/src/main/java/com/tangem/tap/TapApplication.kt
index 5de365ee79..63dfcc0729 100644
--- a/app/src/main/java/com/tangem/tap/TapApplication.kt
+++ b/app/src/main/java/com/tangem/tap/TapApplication.kt
@@ -1,59 +1,68 @@
package com.tangem.tap
-import android.app.*
-import android.content.*
-import android.content.pm.*
-import coil.*
-import com.tangem.*
-import com.tangem.blockchain.common.*
-import com.tangem.blockchain.network.*
-import com.tangem.core.analytics.*
-import com.tangem.core.featuretoggle.manager.*
-import com.tangem.data.source.preferences.*
-import com.tangem.datasource.api.common.*
-import com.tangem.datasource.asset.*
-import com.tangem.datasource.config.*
-import com.tangem.datasource.config.models.*
-import com.tangem.datasource.connection.*
-import com.tangem.domain.*
-import com.tangem.domain.common.*
-import com.tangem.features.wallet.featuretoggles.*
-import com.tangem.tap.common.*
-import com.tangem.tap.common.analytics.*
-import com.tangem.tap.common.analytics.api.*
-import com.tangem.tap.common.analytics.handlers.amplitude.*
-import com.tangem.tap.common.analytics.handlers.appsFlyer.*
-import com.tangem.tap.common.analytics.handlers.firebase.*
-import com.tangem.tap.common.analytics.topup.*
-import com.tangem.tap.common.chat.*
-import com.tangem.tap.common.feedback.*
-import com.tangem.tap.common.images.*
-import com.tangem.tap.common.log.*
-import com.tangem.tap.common.redux.*
-import com.tangem.tap.common.redux.global.*
-import com.tangem.tap.common.shop.*
-import com.tangem.tap.domain.configurable.warningMessage.*
-import com.tangem.tap.domain.tokens.*
-import com.tangem.tap.domain.totalBalance.*
-import com.tangem.tap.domain.totalBalance.di.*
-import com.tangem.tap.domain.walletCurrencies.*
-import com.tangem.tap.domain.walletCurrencies.di.*
-import com.tangem.tap.domain.walletStores.*
-import com.tangem.tap.domain.walletStores.di.*
-import com.tangem.tap.domain.walletStores.repository.*
-import com.tangem.tap.domain.walletStores.repository.di.*
+import android.app.Application
+import android.content.Context
+import android.content.pm.PackageManager
+import coil.ImageLoader
+import coil.ImageLoaderFactory
+import com.tangem.Log
+import com.tangem.LogFormat
+import com.tangem.blockchain.common.BlockchainSdkConfig
+import com.tangem.blockchain.common.WalletManagerFactory
+import com.tangem.blockchain.network.BlockchainSdkRetrofitBuilder
+import com.tangem.core.analytics.Analytics
+import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
+import com.tangem.data.source.preferences.PreferencesDataSource
+import com.tangem.datasource.api.common.MoshiConverter
+import com.tangem.datasource.asset.AssetReader
+import com.tangem.datasource.config.ConfigManager
+import com.tangem.datasource.config.FeaturesLocalLoader
+import com.tangem.datasource.config.models.Config
+import com.tangem.datasource.connection.NetworkConnectionManager
+import com.tangem.domain.DomainLayer
+import com.tangem.domain.common.LogConfig
+import com.tangem.domain.wallets.legacy.WalletManagersRepository
+import com.tangem.feature.learn2earn.domain.api.Learn2earnInteractor
+import com.tangem.features.tokendetails.featuretoggles.TokenDetailsFeatureToggles
+import com.tangem.features.wallet.featuretoggles.WalletFeatureToggles
+import com.tangem.tap.common.analytics.AnalyticsFactory
+import com.tangem.tap.common.analytics.api.AnalyticsHandlerBuilder
+import com.tangem.tap.common.analytics.handlers.amplitude.AmplitudeAnalyticsHandler
+import com.tangem.tap.common.analytics.handlers.appsFlyer.AppsFlyerAnalyticsHandler
+import com.tangem.tap.common.analytics.handlers.firebase.FirebaseAnalyticsHandler
+import com.tangem.tap.common.analytics.topup.TopUpController
+import com.tangem.tap.common.chat.ChatManager
+import com.tangem.tap.common.feedback.AdditionalFeedbackInfo
+import com.tangem.tap.common.feedback.FeedbackManager
+import com.tangem.tap.common.images.createCoilImageLoader
+import com.tangem.tap.common.log.TangemLogCollector
+import com.tangem.tap.common.redux.AppState
+import com.tangem.tap.common.redux.appReducer
+import com.tangem.tap.common.redux.global.GlobalAction
+import com.tangem.tap.common.shop.TangemShopService
+import com.tangem.tap.domain.configurable.warningMessage.WarningMessagesManager
+import com.tangem.tap.domain.tokens.UserTokensRepository
+import com.tangem.tap.domain.totalBalance.TotalFiatBalanceCalculator
+import com.tangem.tap.domain.totalBalance.di.provideDefaultImplementation
+import com.tangem.tap.domain.walletCurrencies.WalletCurrenciesManager
+import com.tangem.tap.domain.walletCurrencies.di.provideDefaultImplementation
+import com.tangem.tap.domain.walletStores.WalletStoresManager
+import com.tangem.tap.domain.walletStores.di.provideDefaultImplementation
+import com.tangem.tap.domain.walletStores.repository.WalletAmountsRepository
+import com.tangem.tap.domain.walletStores.repository.WalletStoresRepository
+import com.tangem.tap.domain.walletStores.repository.di.provideDefaultImplementation
import com.tangem.tap.domain.walletconnect.WalletConnectRepository
-import com.tangem.tap.domain.walletconnect2.domain.*
-import com.tangem.tap.features.customtoken.api.featuretoggles.*
-import com.tangem.tap.proxy.*
-import com.tangem.tap.proxy.redux.*
+import com.tangem.tap.domain.walletconnect2.domain.WalletConnectSessionsRepository
+import com.tangem.tap.features.customtoken.api.featuretoggles.CustomTokenFeatureToggles
+import com.tangem.tap.proxy.AppStateHolder
+import com.tangem.tap.proxy.redux.DaggerGraphState
import com.tangem.wallet.BuildConfig
-import dagger.hilt.android.*
-import kotlinx.coroutines.*
-import okhttp3.logging.*
-import org.rekotlin.*
-import timber.log.*
-import javax.inject.*
+import dagger.hilt.android.HiltAndroidApp
+import kotlinx.coroutines.runBlocking
+import okhttp3.logging.HttpLoggingInterceptor
+import org.rekotlin.Store
+import timber.log.Timber
+import javax.inject.Inject
import com.tangem.tap.domain.walletconnect2.domain.WalletConnectRepository as WalletConnect2Repository
lateinit var store: Store
@@ -102,7 +111,6 @@ val walletCurrenciesManager by lazy {
val totalFiatBalanceCalculator by lazy {
TotalFiatBalanceCalculator.provideDefaultImplementation()
}
-val intentHandler by lazy { IntentHandler() }
@HiltAndroidApp
class TapApplication : Application(), ImageLoaderFactory {
@@ -137,6 +145,12 @@ class TapApplication : Application(), ImageLoaderFactory {
@Inject
lateinit var walletConnectSessionsRepository: WalletConnectSessionsRepository
+ @Inject
+ lateinit var learn2earnInteractor: Learn2earnInteractor
+
+ @Inject
+ lateinit var tokenDetailsFeatureToggles: TokenDetailsFeatureToggles
+
override fun onCreate() {
super.onCreate()
@@ -153,6 +167,7 @@ class TapApplication : Application(), ImageLoaderFactory {
walletFeatureToggles = walletFeatureToggles,
walletConnectRepository = walletConnect2Repository,
walletConnectSessionsRepository = walletConnectSessionsRepository,
+ tokenDetailsFeatureToggles = tokenDetailsFeatureToggles,
),
),
)
@@ -190,8 +205,11 @@ class TapApplication : Application(), ImageLoaderFactory {
appStateHolder.userTokensRepository = userTokensRepository
appStateHolder.walletStoresManager = walletStoresManager
- scope.launch {
+ // TODO: Try to performance and user experience.
+ // [REDACTED_JIRA]
+ runBlocking {
featureTogglesManager.init()
+ learn2earnInteractor.init()
}
initTopUpController()
diff --git a/app/src/main/java/com/tangem/tap/common/IntentHandler.kt b/app/src/main/java/com/tangem/tap/common/IntentHandler.kt
deleted file mode 100644
index 4d50c59679..0000000000
--- a/app/src/main/java/com/tangem/tap/common/IntentHandler.kt
+++ /dev/null
@@ -1,127 +0,0 @@
-package com.tangem.tap.common
-
-import android.content.Intent
-import android.net.Uri
-import android.nfc.NfcAdapter
-import android.nfc.Tag
-import android.os.Build
-import com.tangem.core.analytics.Analytics
-import com.tangem.tap.common.analytics.events.AnalyticsParam
-import com.tangem.tap.common.analytics.events.Token
-import com.tangem.tap.common.extensions.removePrefixOrNull
-import com.tangem.tap.domain.walletconnect.WalletConnectManager
-import com.tangem.tap.features.details.redux.walletconnect.WalletConnectAction
-import com.tangem.tap.features.home.redux.HomeAction
-import com.tangem.tap.features.wallet.redux.WalletAction
-import com.tangem.tap.features.welcome.redux.WelcomeAction
-import com.tangem.tap.network.exchangeServices.ExchangeUrlBuilder
-import com.tangem.tap.scope
-import com.tangem.tap.store
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.launch
-import timber.log.Timber
-
-class IntentHandler {
-
- private val nfcActions = arrayOf(
- NfcAdapter.ACTION_NDEF_DISCOVERED,
- NfcAdapter.ACTION_TECH_DISCOVERED,
- NfcAdapter.ACTION_TAG_DISCOVERED,
- )
-
- fun handleIntent(intent: Intent?, hasSavedUserWallets: Boolean) {
- handleBackgroundScan(intent, hasSavedUserWallets)
- handleWalletConnectLink(intent)
- handleBuyCurrencyCallback(intent)
- handleSellCurrencyCallback(intent)
- }
-
- fun handleWalletConnectLink(intent: Intent?) {
- val wcUri = when (intent?.scheme) {
- WalletConnectManager.WC_SCHEME -> {
- intent.data?.toString()
- }
- TANGEM_SCHEME -> {
- intent.data?.toString()?.removePrefixOrNull(TANGEM_WC_PREFIX)
- }
- else -> {
- null
- }
- }
- if (wcUri != null) {
- store.dispatch(WalletConnectAction.HandleDeepLink(wcUri))
- }
- }
-
- fun handleBackgroundScan(intent: Intent?, hasSavedUserWallets: Boolean): Boolean {
- if (intent == null || intent.action !in nfcActions) return false
-
- val tag: Tag? = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
- intent.getParcelableExtra(NfcAdapter.EXTRA_TAG, Tag::class.java)
- } else {
- @Suppress("DEPRECATION")
- intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
- }
- if (tag == null) return false
-
- intent.action = null
- if (hasSavedUserWallets) {
- // TODO: Remove delay after [REDACTED_JIRA]
- scope.launch {
- delay(timeMillis = 200)
- store.dispatch(WelcomeAction.ProceedWithCard)
- }
- } else {
- store.dispatch(HomeAction.ReadCard())
- }
-
- return true
- }
-
- private fun handleBuyCurrencyCallback(intent: Intent?) {
- val data = intent?.data ?: return
-
- val successUri = Uri.parse(ExchangeUrlBuilder.SUCCESS_URL)
- if (data.host == successUri.host && data.authority == successUri.authority) {
- val currency = store.state.walletState.selectedCurrency ?: return
- val currencyType = AnalyticsParam.CurrencyType.Currency(currency)
- Analytics.send(Token.Bought(currencyType))
- }
- }
-
- fun handleSellCurrencyCallback(intent: Intent?) {
- try {
- val transactionID =
- intent?.data?.getQueryParameter(TRANSACTION_ID_PARAM) ?: return
- val currency =
- intent.data?.getQueryParameter(CURRENCY_CODE_PARAM) ?: return
- val amount =
- intent.data?.getQueryParameter(CURRENCY_AMOUNT_PARAM) ?: return
- val destinationAddress =
- intent.data?.getQueryParameter(DEPOSIT_WALLET_ADDRESS_PARAM)
- ?: return
-
- Timber.d("MoonPay Sell: $amount $currency to $destinationAddress")
-
- store.dispatch(
- WalletAction.TradeCryptoAction.SendCrypto(
- currencyId = currency,
- amount = amount,
- destinationAddress = destinationAddress,
- transactionId = transactionID,
- ),
- )
- } catch (exception: Exception) {
- Timber.d("Not MoonPay URL")
- }
- }
-
- companion object {
- private const val TRANSACTION_ID_PARAM = "transactionId"
- private const val CURRENCY_CODE_PARAM = "baseCurrencyCode"
- private const val CURRENCY_AMOUNT_PARAM = "baseCurrencyAmount"
- private const val DEPOSIT_WALLET_ADDRESS_PARAM = "depositWalletAddress"
- private const val TANGEM_SCHEME = "tangem"
- private const val TANGEM_WC_PREFIX = "tangem://wc?uri="
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/common/analytics/events/AnalyticsParam.kt b/app/src/main/java/com/tangem/tap/common/analytics/events/AnalyticsParam.kt
index 7a788fd5c6..47623e1f10 100644
--- a/app/src/main/java/com/tangem/tap/common/analytics/events/AnalyticsParam.kt
+++ b/app/src/main/java/com/tangem/tap/common/analytics/events/AnalyticsParam.kt
@@ -156,5 +156,6 @@ sealed class AnalyticsParam {
const val ERROR_CODE = "Error Code"
const val ERROR_KEY = "Error Key"
const val CREATION_TYPE = "Creation type"
+ const val DAPP_NAME = "DApp Name"
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/common/analytics/events/Basic.kt b/app/src/main/java/com/tangem/tap/common/analytics/events/Basic.kt
index f4ef3e133f..e5b89b30e5 100644
--- a/app/src/main/java/com/tangem/tap/common/analytics/events/Basic.kt
+++ b/app/src/main/java/com/tangem/tap/common/analytics/events/Basic.kt
@@ -31,12 +31,14 @@ sealed class Basic(
currency: AnalyticsParam.CardCurrency,
batch: String,
signInType: SignInType,
+ walletsCount: String,
) : Basic(
event = "Signed in",
params = mapOf(
AnalyticsParam.CURRENCY to currency.value,
AnalyticsParam.BATCH to batch,
"Sign in type" to signInType.name,
+ "Wallets Count" to walletsCount,
),
) {
enum class SignInType {
diff --git a/app/src/main/java/com/tangem/tap/common/analytics/events/WalletConnect.kt b/app/src/main/java/com/tangem/tap/common/analytics/events/WalletConnect.kt
index 9ce10213ac..34047928e4 100644
--- a/app/src/main/java/com/tangem/tap/common/analytics/events/WalletConnect.kt
+++ b/app/src/main/java/com/tangem/tap/common/analytics/events/WalletConnect.kt
@@ -12,7 +12,13 @@ sealed class WalletConnect(
) : AnalyticsEvent("Wallet Connect", event, params, error) {
class ScreenOpened : WalletConnect(event = "WC Screen Opened")
- class NewSessionEstablished : WalletConnect("New Session Established")
+ class NewSessionEstablished(dAppName: String) : WalletConnect(
+ event = "New Session Established",
+ params = mapOf(
+ AnalyticsParam.DAPP_NAME to dAppName,
+ ),
+ )
+
class SessionDisconnected : WalletConnect("Session Disconnected")
class RequestSigned : WalletConnect("Request Signed")
diff --git a/app/src/main/java/com/tangem/tap/common/analytics/topup/TopUpController.kt b/app/src/main/java/com/tangem/tap/common/analytics/topup/TopUpController.kt
index 97edaae4c1..bdd315bc3d 100644
--- a/app/src/main/java/com/tangem/tap/common/analytics/topup/TopUpController.kt
+++ b/app/src/main/java/com/tangem/tap/common/analytics/topup/TopUpController.kt
@@ -5,19 +5,19 @@ import com.tangem.common.extensions.isZero
import com.tangem.core.analytics.Analytics
import com.tangem.data.source.preferences.model.DataSourceTopupInfo
import com.tangem.data.source.preferences.storage.ToppedUpWalletStorage
+import com.tangem.domain.common.BlockchainNetwork
import com.tangem.domain.common.CardTypesResolver
-import com.tangem.domain.common.util.UserWalletId
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.domain.models.scan.ScanResponse
+import com.tangem.domain.wallets.models.UserWallet
+import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.tap.common.analytics.converters.TopUpEventConverter
import com.tangem.tap.common.analytics.events.AnalyticsParam
import com.tangem.tap.common.extensions.copy
import com.tangem.tap.domain.model.TotalFiatBalance
-import com.tangem.tap.domain.model.UserWallet
import com.tangem.tap.domain.model.WalletDataModel
import com.tangem.tap.domain.model.WalletStoreModel
import com.tangem.tap.domain.model.builders.UserWalletIdBuilder
-import com.tangem.tap.domain.tokens.models.BlockchainNetwork
import com.tangem.tap.domain.walletCurrencies.WalletCurrenciesManager
import com.tangem.tap.domain.walletStores.WalletStoresManager
import com.tangem.tap.features.wallet.models.Currency
diff --git a/app/src/main/java/com/tangem/tap/common/di/domain/wallets/WalletsDomainModule.kt b/app/src/main/java/com/tangem/tap/common/di/domain/wallets/WalletsDomainModule.kt
new file mode 100644
index 0000000000..f945462b83
--- /dev/null
+++ b/app/src/main/java/com/tangem/tap/common/di/domain/wallets/WalletsDomainModule.kt
@@ -0,0 +1,20 @@
+package com.tangem.tap.common.di.domain.wallets
+
+import com.tangem.domain.wallets.legacy.WalletsStateHolder
+import com.tangem.domain.wallets.usecase.GetWalletsUseCase
+import dagger.Module
+import dagger.Provides
+import dagger.hilt.InstallIn
+import dagger.hilt.android.components.ViewModelComponent
+import dagger.hilt.android.scopes.ViewModelScoped
+
+@Module
+@InstallIn(ViewModelComponent::class)
+object WalletsDomainModule {
+
+ @Provides
+ @ViewModelScoped
+ fun providesGetWalletsUseCase(walletsStateHolder: WalletsStateHolder): GetWalletsUseCase {
+ return GetWalletsUseCase(walletsStateHolder = walletsStateHolder)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/common/extensions/Blockchain.kt b/app/src/main/java/com/tangem/tap/common/extensions/Blockchain.kt
index 7ca3e575d4..68aca58758 100644
--- a/app/src/main/java/com/tangem/tap/common/extensions/Blockchain.kt
+++ b/app/src/main/java/com/tangem/tap/common/extensions/Blockchain.kt
@@ -43,6 +43,8 @@ fun Blockchain.getGreyedOutIconRes(): Int {
Blockchain.TerraV1 -> R.drawable.ic_terra_no_color
Blockchain.TerraV2 -> R.drawable.ic_terra2_no_color
Blockchain.Cronos -> R.drawable.ic_cronos_no_color
+ Blockchain.Telos, Blockchain.TelosTestnet -> R.drawable.ic_telos_no_color
+ Blockchain.AlephZero, Blockchain.AlephZeroTestnet -> R.drawable.ic_azero_no_color
else -> R.drawable.ic_tangem_logo
}
}
diff --git a/app/src/main/java/com/tangem/tap/common/extensions/Navigation.kt b/app/src/main/java/com/tangem/tap/common/extensions/Navigation.kt
index f45d14c864..9119734bfd 100644
--- a/app/src/main/java/com/tangem/tap/common/extensions/Navigation.kt
+++ b/app/src/main/java/com/tangem/tap/common/extensions/Navigation.kt
@@ -2,10 +2,10 @@ package com.tangem.tap.common.extensions
import android.os.Bundle
import androidx.fragment.app.*
+import com.tangem.core.navigation.AppScreen
+import com.tangem.core.navigation.FragmentShareTransition
import com.tangem.feature.referral.ReferralFragment
import com.tangem.feature.swap.presentation.SwapFragment
-import com.tangem.tap.common.redux.navigation.AppScreen
-import com.tangem.tap.common.redux.navigation.FragmentShareTransition
import com.tangem.tap.features.customtoken.legacy.AddCustomTokenFragment
import com.tangem.tap.features.details.ui.appsettings.AppSettingsFragment
import com.tangem.tap.features.details.ui.cardsettings.CardSettingsFragment
@@ -167,7 +167,18 @@ private fun fragmentFactory(screen: AppScreen): Fragment {
}
}
- AppScreen.WalletDetails -> WalletDetailsFragment()
+ AppScreen.WalletDetails -> {
+ val featureToggles = store.state.daggerGraphState.get(
+ getDependency = DaggerGraphState::tokenDetailsFeatureToggles,
+ )
+ if (featureToggles.isRedesignedScreenEnabled) {
+ store.state.daggerGraphState
+ .get(getDependency = DaggerGraphState::tokenDetailsRouter)
+ .getEntryFragment()
+ } else {
+ WalletDetailsFragment()
+ }
+ }
AppScreen.WalletConnectSessions -> WalletConnectFragment()
AppScreen.QrScan -> QrScanFragment()
AppScreen.ReferralProgram -> ReferralFragment()
diff --git a/app/src/main/java/com/tangem/tap/common/extensions/Store.kt b/app/src/main/java/com/tangem/tap/common/extensions/Store.kt
index 8b5eafb76f..8676043cd2 100644
--- a/app/src/main/java/com/tangem/tap/common/extensions/Store.kt
+++ b/app/src/main/java/com/tangem/tap/common/extensions/Store.kt
@@ -1,12 +1,12 @@
package com.tangem.tap.common.extensions
+import com.tangem.core.navigation.NavigationAction
import com.tangem.domain.common.extensions.withMainContext
+import com.tangem.domain.wallets.models.UserWallet
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.common.redux.StateDialog
import com.tangem.tap.common.redux.global.GlobalAction
-import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.domain.TapError
-import com.tangem.tap.domain.model.UserWallet
import com.tangem.tap.scope
import com.tangem.tap.store
import kotlinx.coroutines.Dispatchers
diff --git a/app/src/main/java/com/tangem/tap/common/redux/AppState.kt b/app/src/main/java/com/tangem/tap/common/redux/AppState.kt
index 4ebc39d1d2..71be2aa020 100644
--- a/app/src/main/java/com/tangem/tap/common/redux/AppState.kt
+++ b/app/src/main/java/com/tangem/tap/common/redux/AppState.kt
@@ -1,11 +1,11 @@
package com.tangem.tap.common.redux
+import com.tangem.core.navigation.NavigationState
import com.tangem.domain.redux.DomainState
import com.tangem.domain.redux.domainStore
import com.tangem.domain.redux.global.NetworkServices
import com.tangem.tap.common.redux.global.GlobalMiddleware
import com.tangem.tap.common.redux.global.GlobalState
-import com.tangem.tap.common.redux.navigation.NavigationState
import com.tangem.tap.common.redux.navigation.navigationMiddleware
import com.tangem.tap.features.details.redux.DetailsMiddleware
import com.tangem.tap.features.details.redux.DetailsState
diff --git a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalAction.kt b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalAction.kt
index d599f9c378..2d75cf1723 100644
--- a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalAction.kt
+++ b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalAction.kt
@@ -7,19 +7,15 @@ import com.tangem.common.core.TangemError
import com.tangem.datasource.config.ConfigManager
import com.tangem.datasource.config.models.ChatConfig
import com.tangem.domain.models.scan.ScanResponse
+import com.tangem.domain.wallets.legacy.UserWalletsListManager
import com.tangem.tap.common.analytics.topup.TopUpController
import com.tangem.tap.common.entities.FiatCurrency
import com.tangem.tap.common.feedback.FeedbackData
import com.tangem.tap.common.feedback.FeedbackManager
-import com.tangem.tap.common.redux.DebugErrorAction
-import com.tangem.tap.common.redux.ErrorAction
-import com.tangem.tap.common.redux.NotificationAction
-import com.tangem.tap.common.redux.StateDialog
-import com.tangem.tap.common.redux.ToastNotificationAction
+import com.tangem.tap.common.redux.*
import com.tangem.tap.domain.TapError
import com.tangem.tap.domain.configurable.warningMessage.WarningMessage
import com.tangem.tap.domain.configurable.warningMessage.WarningMessagesManager
-import com.tangem.tap.domain.userWalletList.UserWalletsListManager
import com.tangem.tap.features.details.redux.SecurityOption
import org.rekotlin.Action
diff --git a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalState.kt b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalState.kt
index c4becfb45b..1e5a3cfce0 100644
--- a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalState.kt
+++ b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalState.kt
@@ -2,14 +2,13 @@ package com.tangem.tap.common.redux.global
import com.tangem.datasource.config.ConfigManager
import com.tangem.domain.models.scan.ScanResponse
+import com.tangem.domain.wallets.legacy.UserWalletsListManager
import com.tangem.tap.common.analytics.topup.TopUpController
import com.tangem.tap.common.entities.FiatCurrency
import com.tangem.tap.common.feedback.FeedbackManager
import com.tangem.tap.common.redux.StateDialog
-import com.tangem.tap.domain.PayIdManager
import com.tangem.tap.domain.TapWalletManager
import com.tangem.tap.domain.configurable.warningMessage.WarningMessagesManager
-import com.tangem.tap.domain.userWalletList.UserWalletsListManager
import com.tangem.tap.features.onboarding.OnboardingManager
import com.tangem.tap.network.exchangeServices.CurrencyExchangeManager
import org.rekotlin.StateType
@@ -20,7 +19,6 @@ data class GlobalState(
val onboardingState: OnboardingState = OnboardingState(),
val cardVerifiedOnline: Boolean = false,
val tapWalletManager: TapWalletManager = TapWalletManager(),
- val payIdManager: PayIdManager = PayIdManager(),
val configManager: ConfigManager? = null,
val warningManager: WarningMessagesManager? = null,
val feedbackManager: FeedbackManager? = null,
diff --git a/app/src/main/java/com/tangem/tap/common/redux/navigation/NavigationMiddleware.kt b/app/src/main/java/com/tangem/tap/common/redux/navigation/NavigationMiddleware.kt
index bf5df6a9a9..6be8513880 100644
--- a/app/src/main/java/com/tangem/tap/common/redux/navigation/NavigationMiddleware.kt
+++ b/app/src/main/java/com/tangem/tap/common/redux/navigation/NavigationMiddleware.kt
@@ -4,6 +4,8 @@ import android.content.Intent
import android.hardware.biometrics.BiometricManager
import android.os.Build
import android.provider.Settings
+import com.tangem.core.navigation.AppScreen
+import com.tangem.core.navigation.NavigationAction
import com.tangem.tap.activityResultCaller
import com.tangem.tap.common.CustomTabsManager
import com.tangem.tap.common.extensions.dispatchOnMain
diff --git a/app/src/main/java/com/tangem/tap/common/redux/navigation/NavigationReducer.kt b/app/src/main/java/com/tangem/tap/common/redux/navigation/NavigationReducer.kt
index 7febcfa59c..ff53145651 100644
--- a/app/src/main/java/com/tangem/tap/common/redux/navigation/NavigationReducer.kt
+++ b/app/src/main/java/com/tangem/tap/common/redux/navigation/NavigationReducer.kt
@@ -1,5 +1,7 @@
package com.tangem.tap.common.redux.navigation
+import com.tangem.core.navigation.NavigationAction
+import com.tangem.core.navigation.NavigationState
import com.tangem.tap.common.extensions.getPreviousScreen
import com.tangem.tap.common.redux.AppState
import org.rekotlin.Action
diff --git a/app/src/main/java/com/tangem/tap/di/AppStateHolderModule.kt b/app/src/main/java/com/tangem/tap/di/AppStateHolderModule.kt
new file mode 100644
index 0000000000..05cc610f95
--- /dev/null
+++ b/app/src/main/java/com/tangem/tap/di/AppStateHolderModule.kt
@@ -0,0 +1,23 @@
+package com.tangem.tap.di
+
+import com.tangem.core.navigation.NavigationStateHolder
+import com.tangem.domain.wallets.legacy.WalletsStateHolder
+import com.tangem.tap.proxy.AppStateHolder
+import dagger.Binds
+import dagger.Module
+import dagger.hilt.InstallIn
+import dagger.hilt.components.SingletonComponent
+import javax.inject.Singleton
+
+@Module
+@InstallIn(SingletonComponent::class)
+internal interface AppStateHolderModule {
+
+ @Binds
+ @Singleton
+ fun bindsWalletsStateHolder(appStateHolder: AppStateHolder): WalletsStateHolder
+
+ @Binds
+ @Singleton
+ fun bindsNavigationStateHolder(appStateHolder: AppStateHolder): NavigationStateHolder
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/domain/PayIdManager.kt b/app/src/main/java/com/tangem/tap/domain/PayIdManager.kt
deleted file mode 100644
index 11d5300454..0000000000
--- a/app/src/main/java/com/tangem/tap/domain/PayIdManager.kt
+++ /dev/null
@@ -1,56 +0,0 @@
-package com.tangem.tap.domain
-
-import com.tangem.blockchain.common.Blockchain
-import com.tangem.common.services.Result
-import com.tangem.tap.network.payid.PayIdVerifyService
-import com.tangem.tap.network.payid.VerifyPayIdResponse
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.withContext
-import java.util.*
-
-class PayIdManager {
-
- @Suppress("MagicNumber")
- suspend fun verifyPayId(payId: String, blockchain: Blockchain): Result =
- withContext(Dispatchers.IO) {
- val splitPayId = payId.split("\$")
- val user = splitPayId[0]
- val baseUrl = "https://${splitPayId[1]}/"
- return@withContext PayIdVerifyService(baseUrl).verifyAddress(user, blockchain.getPayIdNetwork())
- }
-
- private fun Blockchain.getPayIdNetwork(): String {
- return when (this) {
- Blockchain.XRP -> "XRPL"
- Blockchain.RSK -> "RSK"
- else -> this.currency
- }.lowercase(Locale.getDefault())
- }
-
- companion object {
- private val payIdRegExp = (
- "^[a-z0-9!#@%&*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#@%&*+/=?^_`{|}~-]+)*\\\$(?:(?:[a-z0-9]" +
- "(?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z-]*[a-z0-9])?|(?:[0-9]{1,3}\\.){3}[0-9]{1,3})\$"
- ).toRegex()
-
- val payIdSupported: EnumSet = EnumSet.of(
- Blockchain.XRP,
- Blockchain.Ethereum,
- Blockchain.Bitcoin,
- Blockchain.Litecoin,
- Blockchain.Stellar,
- Blockchain.Cardano,
- Blockchain.CardanoShelley,
- Blockchain.BitcoinCash,
- Blockchain.Binance,
- Blockchain.RSK,
- Blockchain.Tezos,
- )
-
- fun isPayId(value: String?): Boolean = value?.contains(payIdRegExp) ?: false
- }
-}
-
-fun Blockchain.isPayIdSupported(): Boolean {
- return PayIdManager.payIdSupported.contains(this)
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt
index f9be91dcce..23ee5bb963 100644
--- a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt
+++ b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt
@@ -1,6 +1,9 @@
package com.tangem.tap.domain
-import com.tangem.blockchain.common.*
+import com.tangem.blockchain.common.BlockchainSdkConfig
+import com.tangem.blockchain.common.Token
+import com.tangem.blockchain.common.Wallet
+import com.tangem.blockchain.common.WalletManagerFactory
import com.tangem.common.doOnFailure
import com.tangem.common.doOnSuccess
import com.tangem.core.analytics.Analytics
@@ -8,6 +11,7 @@ import com.tangem.datasource.config.ConfigManager
import com.tangem.domain.common.extensions.withMainContext
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.domain.models.scan.ScanResponse
+import com.tangem.domain.wallets.models.UserWallet
import com.tangem.operations.attestation.Attestation
import com.tangem.tap.*
import com.tangem.tap.common.analytics.events.Basic
@@ -15,7 +19,6 @@ import com.tangem.tap.common.extensions.dispatchOnMain
import com.tangem.tap.common.extensions.dispatchWithMain
import com.tangem.tap.common.extensions.setContext
import com.tangem.tap.common.redux.global.GlobalAction
-import com.tangem.tap.domain.model.UserWallet
import com.tangem.tap.domain.walletStores.WalletStoresError
import com.tangem.tap.features.details.redux.walletconnect.WalletConnectAction
import com.tangem.tap.features.disclaimer.createDisclaimer
@@ -134,22 +137,13 @@ class TapWalletManager(
fun updateConfigManager(data: ScanResponse) {
val configManager = store.state.globalState.configManager
- val blockchain = data.cardTypesResolver.getBlockchain()
+
if (data.cardTypesResolver.isStart2Coin()) {
- configManager?.turnOff(ConfigManager.IS_SENDING_TO_PAY_ID_ENABLED)
configManager?.turnOff(ConfigManager.IS_TOP_UP_ENABLED)
- } else if (blockchain == Blockchain.Bitcoin ||
- data.walletData?.blockchain == Blockchain.Bitcoin.id
- ) {
- configManager?.resetToDefault(ConfigManager.IS_SENDING_TO_PAY_ID_ENABLED)
- configManager?.resetToDefault(ConfigManager.IS_TOP_UP_ENABLED)
} else {
- configManager?.resetToDefault(ConfigManager.IS_SENDING_TO_PAY_ID_ENABLED)
configManager?.resetToDefault(ConfigManager.IS_TOP_UP_ENABLED)
}
}
}
-fun Wallet.getFirstToken(): Token? {
- return getTokens().toList().getOrNull(0)
-}
\ No newline at end of file
+fun Wallet.getFirstToken(): Token? = getTokens().toList().getOrNull(index = 0)
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/domain/extensions/WalletManagerFactory.kt b/app/src/main/java/com/tangem/tap/domain/extensions/WalletManagerFactory.kt
index a9de7cb47a..c622163be0 100644
--- a/app/src/main/java/com/tangem/tap/domain/extensions/WalletManagerFactory.kt
+++ b/app/src/main/java/com/tangem/tap/domain/extensions/WalletManagerFactory.kt
@@ -1,20 +1,16 @@
package com.tangem.tap.domain.extensions
-import com.tangem.blockchain.common.Blockchain
-import com.tangem.blockchain.common.DerivationParams
-import com.tangem.blockchain.common.DerivationStyle
-import com.tangem.blockchain.common.WalletManager
-import com.tangem.blockchain.common.WalletManagerFactory
+import com.tangem.blockchain.common.*
import com.tangem.common.card.EllipticCurve
import com.tangem.common.extensions.hexToBytes
import com.tangem.common.extensions.toMapKey
import com.tangem.crypto.hdWallet.DerivationPath
+import com.tangem.domain.common.BlockchainNetwork
import com.tangem.domain.common.TapWorkarounds.isTestCard
import com.tangem.domain.common.TapWorkarounds.useOldStyleDerivation
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.domain.models.scan.CardDTO
import com.tangem.domain.models.scan.ScanResponse
-import com.tangem.tap.domain.tokens.models.BlockchainNetwork
import com.tangem.tap.features.wallet.models.Currency
fun WalletManagerFactory.makeWalletManagerForApp(
diff --git a/app/src/main/java/com/tangem/tap/domain/model/WalletStoreModel.kt b/app/src/main/java/com/tangem/tap/domain/model/WalletStoreModel.kt
index 2dad9e1303..99282954dc 100644
--- a/app/src/main/java/com/tangem/tap/domain/model/WalletStoreModel.kt
+++ b/app/src/main/java/com/tangem/tap/domain/model/WalletStoreModel.kt
@@ -3,9 +3,9 @@ package com.tangem.tap.domain.model
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.WalletManager
import com.tangem.crypto.hdWallet.DerivationPath
-import com.tangem.domain.common.util.UserWalletId
+import com.tangem.domain.common.BlockchainNetwork
+import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.tap.domain.model.WalletStoreModel.WalletRent
-import com.tangem.tap.domain.tokens.models.BlockchainNetwork
import com.tangem.tap.features.wallet.models.Currency
import java.math.BigDecimal
diff --git a/app/src/main/java/com/tangem/tap/domain/model/builders/UserWalletBuilder.kt b/app/src/main/java/com/tangem/tap/domain/model/builders/UserWalletBuilder.kt
index d4e6cbd1fc..7fa72a04fa 100644
--- a/app/src/main/java/com/tangem/tap/domain/model/builders/UserWalletBuilder.kt
+++ b/app/src/main/java/com/tangem/tap/domain/model/builders/UserWalletBuilder.kt
@@ -1,11 +1,11 @@
package com.tangem.tap.domain.model.builders
+import com.tangem.domain.common.TapWorkarounds.isStart2Coin
+import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.domain.models.scan.CardDTO
import com.tangem.domain.models.scan.ProductType
import com.tangem.domain.models.scan.ScanResponse
-import com.tangem.domain.common.TapWorkarounds.isStart2Coin
-import com.tangem.domain.common.util.cardTypesResolver
-import com.tangem.tap.domain.model.UserWallet
+import com.tangem.domain.wallets.models.UserWallet
import com.tangem.tap.domain.userWalletList.GetCardImageUseCase
class UserWalletBuilder(
diff --git a/app/src/main/java/com/tangem/tap/domain/model/builders/UserWalletIdBuilder.kt b/app/src/main/java/com/tangem/tap/domain/model/builders/UserWalletIdBuilder.kt
index 64f5f8156d..30b4ef4407 100644
--- a/app/src/main/java/com/tangem/tap/domain/model/builders/UserWalletIdBuilder.kt
+++ b/app/src/main/java/com/tangem/tap/domain/model/builders/UserWalletIdBuilder.kt
@@ -3,12 +3,12 @@ package com.tangem.tap.domain.model.builders
import com.tangem.common.extensions.calculateSha256
import com.tangem.common.extensions.hexToBytes
import com.tangem.crypto.Secp256k1
+import com.tangem.domain.common.TapWorkarounds.isTangemTwins
+import com.tangem.domain.common.extensions.calculateHmacSha256
import com.tangem.domain.models.scan.CardDTO
import com.tangem.domain.models.scan.ProductType
import com.tangem.domain.models.scan.ScanResponse
-import com.tangem.domain.common.TapWorkarounds.isTangemTwins
-import com.tangem.domain.common.extensions.calculateHmacSha256
-import com.tangem.domain.common.util.UserWalletId
+import com.tangem.domain.wallets.models.UserWalletId
class UserWalletIdBuilder private constructor(
private val publicKey: ByteArray?,
diff --git a/app/src/main/java/com/tangem/tap/domain/model/builders/WalletStoreBuilder.kt b/app/src/main/java/com/tangem/tap/domain/model/builders/WalletStoreBuilder.kt
index e7d01ecdb6..81532e5bb9 100644
--- a/app/src/main/java/com/tangem/tap/domain/model/builders/WalletStoreBuilder.kt
+++ b/app/src/main/java/com/tangem/tap/domain/model/builders/WalletStoreBuilder.kt
@@ -1,18 +1,14 @@
package com.tangem.tap.domain.model.builders
import com.tangem.blockchain.blockchains.polkadot.ExistentialDepositProvider
-import com.tangem.blockchain.common.Blockchain
-import com.tangem.blockchain.common.DerivationStyle
-import com.tangem.blockchain.common.Token
-import com.tangem.blockchain.common.Wallet
-import com.tangem.blockchain.common.WalletManager
+import com.tangem.blockchain.common.*
import com.tangem.crypto.hdWallet.DerivationPath
+import com.tangem.domain.common.BlockchainNetwork
import com.tangem.domain.common.TapWorkarounds.derivationStyle
import com.tangem.domain.common.util.cardTypesResolver
-import com.tangem.tap.domain.model.UserWallet
+import com.tangem.domain.wallets.models.UserWallet
import com.tangem.tap.domain.model.WalletDataModel
import com.tangem.tap.domain.model.WalletStoreModel
-import com.tangem.tap.domain.tokens.models.BlockchainNetwork
import com.tangem.tap.features.wallet.models.Currency
import com.tangem.tap.features.wallet.redux.reducers.createAddressesData
import java.math.BigDecimal
diff --git a/app/src/main/java/com/tangem/tap/domain/scanCard/LegacyScanProcessor.kt b/app/src/main/java/com/tangem/tap/domain/scanCard/LegacyScanProcessor.kt
index f885b4fa13..e83d2496ff 100644
--- a/app/src/main/java/com/tangem/tap/domain/scanCard/LegacyScanProcessor.kt
+++ b/app/src/main/java/com/tangem/tap/domain/scanCard/LegacyScanProcessor.kt
@@ -7,6 +7,8 @@ import com.tangem.common.doOnFailure
import com.tangem.common.doOnSuccess
import com.tangem.core.analytics.Analytics
import com.tangem.core.analytics.AnalyticsEvent
+import com.tangem.core.navigation.AppScreen
+import com.tangem.core.navigation.NavigationAction
import com.tangem.domain.common.extensions.withMainContext
import com.tangem.domain.common.util.twinsIsTwinned
import com.tangem.domain.models.scan.ScanResponse
@@ -14,8 +16,6 @@ import com.tangem.tap.*
import com.tangem.tap.common.analytics.paramsInterceptor.CardContextInterceptor
import com.tangem.tap.common.extensions.*
import com.tangem.tap.common.redux.global.GlobalAction
-import com.tangem.tap.common.redux.navigation.AppScreen
-import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.features.disclaimer.createDisclaimer
import com.tangem.tap.features.disclaimer.redux.DisclaimerAction
import com.tangem.tap.features.disclaimer.redux.DisclaimerCallback
diff --git a/app/src/main/java/com/tangem/tap/domain/scanCard/UseCaseScanProcessor.kt b/app/src/main/java/com/tangem/tap/domain/scanCard/UseCaseScanProcessor.kt
index 45a463343a..ae4e286e5f 100644
--- a/app/src/main/java/com/tangem/tap/domain/scanCard/UseCaseScanProcessor.kt
+++ b/app/src/main/java/com/tangem/tap/domain/scanCard/UseCaseScanProcessor.kt
@@ -4,12 +4,12 @@ import arrow.fx.coroutines.resourceScope
import com.tangem.common.CompletionResult
import com.tangem.common.core.TangemError
import com.tangem.core.analytics.AnalyticsEvent
+import com.tangem.core.navigation.AppScreen
+import com.tangem.core.navigation.NavigationAction
import com.tangem.domain.card.ScanCardException
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.tap.DELAY_SDK_DIALOG_CLOSE
import com.tangem.tap.common.extensions.dispatchOnMain
-import com.tangem.tap.common.redux.navigation.AppScreen
-import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.domain.scanCard.chains.*
import com.tangem.tap.domain.scanCard.utils.ScanCardExceptionConverter
import com.tangem.tap.preferencesStorage
diff --git a/app/src/main/java/com/tangem/tap/domain/scanCard/chains/CheckForOnboardingChain.kt b/app/src/main/java/com/tangem/tap/domain/scanCard/chains/CheckForOnboardingChain.kt
index ce46f2f527..baa5c93445 100644
--- a/app/src/main/java/com/tangem/tap/domain/scanCard/chains/CheckForOnboardingChain.kt
+++ b/app/src/main/java/com/tangem/tap/domain/scanCard/chains/CheckForOnboardingChain.kt
@@ -4,6 +4,7 @@ import arrow.core.Either
import arrow.core.left
import arrow.core.right
import com.tangem.core.analytics.Analytics
+import com.tangem.core.navigation.AppScreen
import com.tangem.data.source.preferences.PreferencesDataSource
import com.tangem.domain.card.ScanCardException
import com.tangem.domain.common.util.twinsIsTwinned
@@ -15,7 +16,6 @@ import com.tangem.tap.common.extensions.dispatchOnMain
import com.tangem.tap.common.extensions.setContext
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.common.redux.global.GlobalAction
-import com.tangem.tap.common.redux.navigation.AppScreen
import com.tangem.tap.domain.TapWalletManager
import com.tangem.tap.features.onboarding.OnboardingHelper
import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsAction
diff --git a/app/src/main/java/com/tangem/tap/domain/scanCard/chains/DisclaimerChain.kt b/app/src/main/java/com/tangem/tap/domain/scanCard/chains/DisclaimerChain.kt
index b1addc1718..ccf4f495bd 100644
--- a/app/src/main/java/com/tangem/tap/domain/scanCard/chains/DisclaimerChain.kt
+++ b/app/src/main/java/com/tangem/tap/domain/scanCard/chains/DisclaimerChain.kt
@@ -3,12 +3,12 @@ package com.tangem.tap.domain.scanCard.chains
import arrow.core.Either
import arrow.core.left
import arrow.core.right
+import com.tangem.core.navigation.AppScreen
import com.tangem.domain.card.ScanCardException
import com.tangem.domain.core.chain.Chain
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.tap.common.extensions.dispatchOnMain
import com.tangem.tap.common.redux.AppState
-import com.tangem.tap.common.redux.navigation.AppScreen
import com.tangem.tap.features.disclaimer.Disclaimer
import com.tangem.tap.features.disclaimer.createDisclaimer
import com.tangem.tap.features.disclaimer.redux.DisclaimerAction
diff --git a/app/src/main/java/com/tangem/tap/domain/scanCard/chains/ScanChainException.kt b/app/src/main/java/com/tangem/tap/domain/scanCard/chains/ScanChainException.kt
index 6709cb8966..588dc809e2 100644
--- a/app/src/main/java/com/tangem/tap/domain/scanCard/chains/ScanChainException.kt
+++ b/app/src/main/java/com/tangem/tap/domain/scanCard/chains/ScanChainException.kt
@@ -1,7 +1,7 @@
package com.tangem.tap.domain.scanCard.chains
+import com.tangem.core.navigation.AppScreen
import com.tangem.domain.card.ScanCardException
-import com.tangem.tap.common.redux.navigation.AppScreen
sealed class ScanChainException : ScanCardException.ChainException() {
diff --git a/app/src/main/java/com/tangem/tap/domain/tasks/product/ScanProductTask.kt b/app/src/main/java/com/tangem/tap/domain/tasks/product/ScanProductTask.kt
index 69a78dfb46..663e931472 100644
--- a/app/src/main/java/com/tangem/tap/domain/tasks/product/ScanProductTask.kt
+++ b/app/src/main/java/com/tangem/tap/domain/tasks/product/ScanProductTask.kt
@@ -8,16 +8,12 @@ import com.tangem.common.core.CardSessionRunnable
import com.tangem.common.core.TangemError
import com.tangem.common.core.TangemSdkError
import com.tangem.common.deserialization.WalletDataDeserializer
-import com.tangem.common.extensions.ByteArrayKey
-import com.tangem.common.extensions.guard
-import com.tangem.common.extensions.hexToBytes
-import com.tangem.common.extensions.toByteArray
-import com.tangem.common.extensions.toHexString
-import com.tangem.common.extensions.toMapKey
+import com.tangem.common.extensions.*
import com.tangem.common.tlv.Tlv
import com.tangem.common.tlv.TlvDecoder
import com.tangem.crypto.CryptoUtils
import com.tangem.crypto.hdWallet.DerivationPath
+import com.tangem.domain.common.BlockchainNetwork
import com.tangem.domain.common.TapWorkarounds.isExcluded
import com.tangem.domain.common.TapWorkarounds.isNotSupportedInThatRelease
import com.tangem.domain.common.TapWorkarounds.isStart2Coin
@@ -36,10 +32,10 @@ import com.tangem.operations.issuerAndUserData.ReadIssuerDataCommand
import com.tangem.tap.domain.TapSdkError
import com.tangem.tap.domain.extensions.getPrimaryCurve
import com.tangem.tap.domain.tokens.UserTokensRepository
-import com.tangem.tap.domain.tokens.models.BlockchainNetwork
import com.tangem.tap.preferencesStorage
import com.tangem.tap.scope
import kotlinx.coroutines.launch
+import kotlin.collections.set
class ScanProductTask(
val card: Card? = null,
diff --git a/app/src/main/java/com/tangem/tap/domain/tokens/UserTokensRepository.kt b/app/src/main/java/com/tangem/tap/domain/tokens/UserTokensRepository.kt
index ff7517ff1a..c4c01684bf 100644
--- a/app/src/main/java/com/tangem/tap/domain/tokens/UserTokensRepository.kt
+++ b/app/src/main/java/com/tangem/tap/domain/tokens/UserTokensRepository.kt
@@ -8,10 +8,10 @@ import com.tangem.datasource.api.tangemTech.TangemTechService
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
import com.tangem.datasource.connection.NetworkConnectionManager
import com.tangem.datasource.files.AndroidFileReader
+import com.tangem.domain.common.BlockchainNetwork
import com.tangem.domain.models.scan.CardDTO
import com.tangem.tap.domain.model.builders.UserWalletIdBuilder
import com.tangem.tap.domain.tokens.converters.CurrencyConverter
-import com.tangem.tap.domain.tokens.models.BlockchainNetwork
import com.tangem.tap.features.demo.DemoHelper
import com.tangem.tap.features.wallet.models.Currency
import com.tangem.tap.features.wallet.models.toBlockchainNetworks
diff --git a/app/src/main/java/com/tangem/tap/domain/userWalletList/UserWalletsListManagerExtensions.kt b/app/src/main/java/com/tangem/tap/domain/userWalletList/UserWalletsListManagerExtensions.kt
index b795c7df78..8086bded7c 100644
--- a/app/src/main/java/com/tangem/tap/domain/userWalletList/UserWalletsListManagerExtensions.kt
+++ b/app/src/main/java/com/tangem/tap/domain/userWalletList/UserWalletsListManagerExtensions.kt
@@ -1,7 +1,8 @@
package com.tangem.tap.domain.userWalletList
import com.tangem.common.CompletionResult
-import com.tangem.tap.domain.model.UserWallet
+import com.tangem.domain.wallets.legacy.UserWalletsListManager
+import com.tangem.domain.wallets.models.UserWallet
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOf
diff --git a/app/src/main/java/com/tangem/tap/domain/userWalletList/di/UserWalletsListManagerProvider.kt b/app/src/main/java/com/tangem/tap/domain/userWalletList/di/UserWalletsListManagerProvider.kt
index 71255de6a0..5f02cd1258 100644
--- a/app/src/main/java/com/tangem/tap/domain/userWalletList/di/UserWalletsListManagerProvider.kt
+++ b/app/src/main/java/com/tangem/tap/domain/userWalletList/di/UserWalletsListManagerProvider.kt
@@ -5,22 +5,17 @@ import com.squareup.moshi.Moshi
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
import com.tangem.common.json.TangemSdkAdapter
import com.tangem.common.services.secure.SecureStorage
+import com.tangem.domain.wallets.legacy.UserWalletsListManager
import com.tangem.sdk.storage.AndroidSecureStorage
import com.tangem.sdk.storage.createEncryptedSharedPreferences
import com.tangem.tap.domain.TangemSdkManager
-import com.tangem.tap.domain.userWalletList.UserWalletsListManager
import com.tangem.tap.domain.userWalletList.implementation.BiometricUserWalletsListManager
import com.tangem.tap.domain.userWalletList.implementation.RuntimeUserWalletsListManager
import com.tangem.tap.domain.userWalletList.repository.implementation.BiometricUserWalletsKeysRepository
import com.tangem.tap.domain.userWalletList.repository.implementation.DefaultSelectedUserWalletRepository
import com.tangem.tap.domain.userWalletList.repository.implementation.DefaultUserWalletsPublicInformationRepository
import com.tangem.tap.domain.userWalletList.repository.implementation.DefaultUserWalletsSensitiveInformationRepository
-import com.tangem.tap.domain.userWalletList.utils.json.ByteArrayKeyAdapter
-import com.tangem.tap.domain.userWalletList.utils.json.CardBackupStatusAdapter
-import com.tangem.tap.domain.userWalletList.utils.json.DerivationPathAdapterWithMigration
-import com.tangem.tap.domain.userWalletList.utils.json.ExtendedPublicKeysMapAdapter
-import com.tangem.tap.domain.userWalletList.utils.json.ScanResponseDerivedKeysMapAdapter
-import com.tangem.tap.domain.userWalletList.utils.json.WalletDerivedKeysMapAdapter
+import com.tangem.tap.domain.userWalletList.utils.json.*
private const val USER_WALLETS_STORAGE_NAME = "user_wallets_storage"
diff --git a/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/BiometricUserWalletsListManager.kt b/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/BiometricUserWalletsListManager.kt
index 4ea180e270..18ec89cb9c 100644
--- a/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/BiometricUserWalletsListManager.kt
+++ b/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/BiometricUserWalletsListManager.kt
@@ -2,10 +2,10 @@ package com.tangem.tap.domain.userWalletList.implementation
import com.tangem.common.*
import com.tangem.common.extensions.guard
-import com.tangem.domain.common.util.UserWalletId
-import com.tangem.tap.domain.model.UserWallet
+import com.tangem.domain.wallets.legacy.UserWalletsListManager
+import com.tangem.domain.wallets.models.UserWallet
+import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.tap.domain.userWalletList.UserWalletsListError
-import com.tangem.tap.domain.userWalletList.UserWalletsListManager
import com.tangem.tap.domain.userWalletList.model.UserWalletEncryptionKey
import com.tangem.tap.domain.userWalletList.repository.SelectedUserWalletRepository
import com.tangem.tap.domain.userWalletList.repository.UserWalletsKeysRepository
@@ -53,6 +53,9 @@ internal class BiometricUserWalletsListManager(
override val hasUserWallets: Boolean
get() = keysRepository.hasSavedEncryptionKeys()
+ override val walletsCount: Int
+ get() = state.value.userWallets.size
+
override suspend fun unlock(): CompletionResult {
return unlockWithBiometryInternal()
.mapFailure { error ->
diff --git a/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/RuntimeUserWalletsListManager.kt b/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/RuntimeUserWalletsListManager.kt
index c94958d46f..d1cd26b6ff 100644
--- a/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/RuntimeUserWalletsListManager.kt
+++ b/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/RuntimeUserWalletsListManager.kt
@@ -2,18 +2,12 @@ package com.tangem.tap.domain.userWalletList.implementation
import com.tangem.common.CompletionResult
import com.tangem.common.catching
-import com.tangem.domain.common.util.UserWalletId
-import com.tangem.tap.domain.model.UserWallet
+import com.tangem.domain.wallets.legacy.UserWalletsListManager
+import com.tangem.domain.wallets.models.UserWallet
+import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.tap.domain.userWalletList.UserWalletsListError
-import com.tangem.tap.domain.userWalletList.UserWalletsListManager
import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.distinctUntilChanged
-import kotlinx.coroutines.flow.filterNotNull
-import kotlinx.coroutines.flow.mapLatest
-import kotlinx.coroutines.flow.update
-import kotlinx.coroutines.flow.updateAndGet
+import kotlinx.coroutines.flow.*
@OptIn(ExperimentalCoroutinesApi::class)
internal class RuntimeUserWalletsListManager : UserWalletsListManager {
@@ -36,6 +30,12 @@ internal class RuntimeUserWalletsListManager : UserWalletsListManager {
override val hasUserWallets: Boolean
get() = state.value.userWallet != null
+ /**
+ * only 1 wallet stored in runtime implementation
+ */
+ override val walletsCount: Int
+ get() = 1
+
override suspend fun select(userWalletId: UserWalletId): CompletionResult = catching {
state.value.userWallet
?.takeIf { it.walletId == userWalletId }
diff --git a/app/src/main/java/com/tangem/tap/domain/userWalletList/model/UserWalletEncryptionKey.kt b/app/src/main/java/com/tangem/tap/domain/userWalletList/model/UserWalletEncryptionKey.kt
index df0f473bae..d17ee7c4a3 100644
--- a/app/src/main/java/com/tangem/tap/domain/userWalletList/model/UserWalletEncryptionKey.kt
+++ b/app/src/main/java/com/tangem/tap/domain/userWalletList/model/UserWalletEncryptionKey.kt
@@ -1,7 +1,7 @@
package com.tangem.tap.domain.userWalletList.model
import com.squareup.moshi.JsonClass
-import com.tangem.domain.common.util.UserWalletId
+import com.tangem.domain.wallets.models.UserWalletId
@JsonClass(generateAdapter = true)
internal data class UserWalletEncryptionKey(
diff --git a/app/src/main/java/com/tangem/tap/domain/userWalletList/model/UserWalletInformation.kt b/app/src/main/java/com/tangem/tap/domain/userWalletList/model/UserWalletInformation.kt
index d81f8ebafc..fe064832d6 100644
--- a/app/src/main/java/com/tangem/tap/domain/userWalletList/model/UserWalletInformation.kt
+++ b/app/src/main/java/com/tangem/tap/domain/userWalletList/model/UserWalletInformation.kt
@@ -3,7 +3,7 @@ package com.tangem.tap.domain.userWalletList.model
import com.squareup.moshi.JsonClass
import com.tangem.domain.models.scan.CardDTO
import com.tangem.domain.models.scan.ScanResponse
-import com.tangem.domain.common.util.UserWalletId
+import com.tangem.domain.wallets.models.UserWalletId
@JsonClass(generateAdapter = true)
internal data class UserWalletSensitiveInformation(
diff --git a/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/SelectedUserWalletRepository.kt b/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/SelectedUserWalletRepository.kt
index aee7766d49..61c2a2eec4 100644
--- a/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/SelectedUserWalletRepository.kt
+++ b/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/SelectedUserWalletRepository.kt
@@ -1,6 +1,6 @@
package com.tangem.tap.domain.userWalletList.repository
-import com.tangem.domain.common.util.UserWalletId
+import com.tangem.domain.wallets.models.UserWalletId
internal interface SelectedUserWalletRepository {
fun get(): UserWalletId?
diff --git a/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/UserWalletsKeysRepository.kt b/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/UserWalletsKeysRepository.kt
index 99b62dc99d..08c509a16c 100644
--- a/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/UserWalletsKeysRepository.kt
+++ b/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/UserWalletsKeysRepository.kt
@@ -1,7 +1,7 @@
package com.tangem.tap.domain.userWalletList.repository
import com.tangem.common.CompletionResult
-import com.tangem.domain.common.util.UserWalletId
+import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.tap.domain.userWalletList.model.UserWalletEncryptionKey
internal interface UserWalletsKeysRepository {
diff --git a/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/UserWalletsPublicInformationRepository.kt b/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/UserWalletsPublicInformationRepository.kt
index 8765a6b804..6b40cf721e 100644
--- a/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/UserWalletsPublicInformationRepository.kt
+++ b/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/UserWalletsPublicInformationRepository.kt
@@ -1,8 +1,8 @@
package com.tangem.tap.domain.userWalletList.repository
import com.tangem.common.CompletionResult
-import com.tangem.domain.common.util.UserWalletId
-import com.tangem.tap.domain.model.UserWallet
+import com.tangem.domain.wallets.models.UserWallet
+import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.tap.domain.userWalletList.model.UserWalletPublicInformation
internal interface UserWalletsPublicInformationRepository {
diff --git a/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/UserWalletsSensitiveInformationRepository.kt b/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/UserWalletsSensitiveInformationRepository.kt
index fdae3e64a0..15d9abbee4 100644
--- a/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/UserWalletsSensitiveInformationRepository.kt
+++ b/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/UserWalletsSensitiveInformationRepository.kt
@@ -1,8 +1,8 @@
package com.tangem.tap.domain.userWalletList.repository
import com.tangem.common.CompletionResult
-import com.tangem.domain.common.util.UserWalletId
-import com.tangem.tap.domain.model.UserWallet
+import com.tangem.domain.wallets.models.UserWallet
+import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.tap.domain.userWalletList.model.UserWalletEncryptionKey
import com.tangem.tap.domain.userWalletList.model.UserWalletSensitiveInformation
diff --git a/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/implementation/BiometricUserWalletsKeysRepository.kt b/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/implementation/BiometricUserWalletsKeysRepository.kt
index affeeeef57..b8c9ce2bc5 100644
--- a/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/implementation/BiometricUserWalletsKeysRepository.kt
+++ b/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/implementation/BiometricUserWalletsKeysRepository.kt
@@ -3,17 +3,12 @@ package com.tangem.tap.domain.userWalletList.repository.implementation
import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.Moshi
import com.squareup.moshi.Types
-import com.tangem.common.CompletionResult
+import com.tangem.common.*
import com.tangem.common.biometric.BiometricManager
import com.tangem.common.biometric.BiometricStorage
import com.tangem.common.core.TangemSdkError
-import com.tangem.common.doOnFailure
-import com.tangem.common.flatMapOnFailure
-import com.tangem.common.fold
-import com.tangem.common.map
-import com.tangem.common.mapFailure
import com.tangem.common.services.secure.SecureStorage
-import com.tangem.domain.common.util.UserWalletId
+import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.tap.domain.userWalletList.UserWalletsListError
import com.tangem.tap.domain.userWalletList.model.UserWalletEncryptionKey
import com.tangem.tap.domain.userWalletList.repository.UserWalletsKeysRepository
diff --git a/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/implementation/DefaultSelectedUserWalletRepository.kt b/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/implementation/DefaultSelectedUserWalletRepository.kt
index 6efa84fc70..e30816c98c 100644
--- a/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/implementation/DefaultSelectedUserWalletRepository.kt
+++ b/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/implementation/DefaultSelectedUserWalletRepository.kt
@@ -1,7 +1,7 @@
package com.tangem.tap.domain.userWalletList.repository.implementation
import com.tangem.common.services.secure.SecureStorage
-import com.tangem.domain.common.util.UserWalletId
+import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.tap.domain.userWalletList.repository.SelectedUserWalletRepository
internal class DefaultSelectedUserWalletRepository(
diff --git a/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/implementation/DefaultUserWalletsPublicInformationRepository.kt b/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/implementation/DefaultUserWalletsPublicInformationRepository.kt
index ab64d4a5fb..cadd73b606 100644
--- a/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/implementation/DefaultUserWalletsPublicInformationRepository.kt
+++ b/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/implementation/DefaultUserWalletsPublicInformationRepository.kt
@@ -7,9 +7,9 @@ import com.tangem.common.CompletionResult
import com.tangem.common.catching
import com.tangem.common.flatMap
import com.tangem.common.services.secure.SecureStorage
-import com.tangem.domain.common.util.UserWalletId
+import com.tangem.domain.wallets.models.UserWallet
+import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.tap.common.extensions.replaceByOrAdd
-import com.tangem.tap.domain.model.UserWallet
import com.tangem.tap.domain.userWalletList.model.UserWalletPublicInformation
import com.tangem.tap.domain.userWalletList.repository.UserWalletsPublicInformationRepository
import com.tangem.tap.domain.userWalletList.utils.publicInformation
diff --git a/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/implementation/DefaultUserWalletsSensitiveInformationRepository.kt b/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/implementation/DefaultUserWalletsSensitiveInformationRepository.kt
index 631d8d13c6..8c67c90889 100644
--- a/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/implementation/DefaultUserWalletsSensitiveInformationRepository.kt
+++ b/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/implementation/DefaultUserWalletsSensitiveInformationRepository.kt
@@ -7,9 +7,9 @@ import com.squareup.moshi.Types
import com.tangem.common.CompletionResult
import com.tangem.common.catching
import com.tangem.common.services.secure.SecureStorage
-import com.tangem.domain.common.util.UserWalletId
+import com.tangem.domain.wallets.models.UserWallet
+import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.tap.common.extensions.filterNotNull
-import com.tangem.tap.domain.model.UserWallet
import com.tangem.tap.domain.userWalletList.model.UserWalletEncryptionKey
import com.tangem.tap.domain.userWalletList.model.UserWalletSensitiveInformation
import com.tangem.tap.domain.userWalletList.repository.UserWalletsSensitiveInformationRepository
diff --git a/app/src/main/java/com/tangem/tap/domain/userWalletList/utils/Mapper.kt b/app/src/main/java/com/tangem/tap/domain/userWalletList/utils/Mapper.kt
index 4c7784a50a..4116cde096 100644
--- a/app/src/main/java/com/tangem/tap/domain/userWalletList/utils/Mapper.kt
+++ b/app/src/main/java/com/tangem/tap/domain/userWalletList/utils/Mapper.kt
@@ -1,7 +1,7 @@
package com.tangem.tap.domain.userWalletList.utils
-import com.tangem.domain.common.util.UserWalletId
-import com.tangem.tap.domain.model.UserWallet
+import com.tangem.domain.wallets.models.UserWallet
+import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.tap.domain.userWalletList.model.UserWalletPublicInformation
import com.tangem.tap.domain.userWalletList.model.UserWalletSensitiveInformation
diff --git a/app/src/main/java/com/tangem/tap/domain/walletCurrencies/WalletCurrenciesManager.kt b/app/src/main/java/com/tangem/tap/domain/walletCurrencies/WalletCurrenciesManager.kt
index f56949a1be..413550b22e 100644
--- a/app/src/main/java/com/tangem/tap/domain/walletCurrencies/WalletCurrenciesManager.kt
+++ b/app/src/main/java/com/tangem/tap/domain/walletCurrencies/WalletCurrenciesManager.kt
@@ -1,7 +1,7 @@
package com.tangem.tap.domain.walletCurrencies
import com.tangem.common.CompletionResult
-import com.tangem.tap.domain.model.UserWallet
+import com.tangem.domain.wallets.models.UserWallet
import com.tangem.tap.features.wallet.models.Currency
interface WalletCurrenciesManager {
diff --git a/app/src/main/java/com/tangem/tap/domain/walletCurrencies/di/WalletCurrenciesManagerProvider.kt b/app/src/main/java/com/tangem/tap/domain/walletCurrencies/di/WalletCurrenciesManagerProvider.kt
index 0c6bfccf02..bf2d47611e 100644
--- a/app/src/main/java/com/tangem/tap/domain/walletCurrencies/di/WalletCurrenciesManagerProvider.kt
+++ b/app/src/main/java/com/tangem/tap/domain/walletCurrencies/di/WalletCurrenciesManagerProvider.kt
@@ -1,11 +1,11 @@
package com.tangem.tap.domain.walletCurrencies.di
+import com.tangem.domain.wallets.legacy.WalletManagersRepository
import com.tangem.tap.common.entities.FiatCurrency
import com.tangem.tap.domain.tokens.UserTokensRepository
import com.tangem.tap.domain.walletCurrencies.WalletCurrenciesManager
import com.tangem.tap.domain.walletCurrencies.implementation.DefaultWalletCurrenciesManager
import com.tangem.tap.domain.walletStores.repository.WalletAmountsRepository
-import com.tangem.tap.domain.walletStores.repository.WalletManagersRepository
import com.tangem.tap.domain.walletStores.repository.WalletStoresRepository
fun WalletCurrenciesManager.Companion.provideDefaultImplementation(
diff --git a/app/src/main/java/com/tangem/tap/domain/walletCurrencies/implementation/DefaultWalletCurrenciesManager.kt b/app/src/main/java/com/tangem/tap/domain/walletCurrencies/implementation/DefaultWalletCurrenciesManager.kt
index 0bbd76b7bc..07e8b8ccf6 100644
--- a/app/src/main/java/com/tangem/tap/domain/walletCurrencies/implementation/DefaultWalletCurrenciesManager.kt
+++ b/app/src/main/java/com/tangem/tap/domain/walletCurrencies/implementation/DefaultWalletCurrenciesManager.kt
@@ -2,17 +2,17 @@ package com.tangem.tap.domain.walletCurrencies.implementation
import com.tangem.blockchain.common.DerivationStyle
import com.tangem.common.*
+import com.tangem.domain.common.BlockchainNetwork
import com.tangem.domain.common.TapWorkarounds.derivationStyle
-import com.tangem.domain.common.util.UserWalletId
import com.tangem.domain.models.scan.CardDTO
+import com.tangem.domain.wallets.legacy.WalletManagersRepository
+import com.tangem.domain.wallets.models.UserWallet
+import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.tap.common.entities.FiatCurrency
-import com.tangem.tap.domain.model.UserWallet
import com.tangem.tap.domain.model.builders.WalletStoreBuilder
import com.tangem.tap.domain.tokens.UserTokensRepository
-import com.tangem.tap.domain.tokens.models.BlockchainNetwork
import com.tangem.tap.domain.walletCurrencies.WalletCurrenciesManager
import com.tangem.tap.domain.walletStores.repository.WalletAmountsRepository
-import com.tangem.tap.domain.walletStores.repository.WalletManagersRepository
import com.tangem.tap.domain.walletStores.repository.WalletStoresRepository
import com.tangem.tap.features.wallet.models.Currency
import com.tangem.tap.features.wallet.models.toBlockchainNetworks
diff --git a/app/src/main/java/com/tangem/tap/domain/walletStores/WalletStoresManager.kt b/app/src/main/java/com/tangem/tap/domain/walletStores/WalletStoresManager.kt
index 867e75e174..10d89c17eb 100644
--- a/app/src/main/java/com/tangem/tap/domain/walletStores/WalletStoresManager.kt
+++ b/app/src/main/java/com/tangem/tap/domain/walletStores/WalletStoresManager.kt
@@ -2,8 +2,8 @@ package com.tangem.tap.domain.walletStores
import com.tangem.blockchain.common.address.AddressType
import com.tangem.common.CompletionResult
-import com.tangem.domain.common.util.UserWalletId
-import com.tangem.tap.domain.model.UserWallet
+import com.tangem.domain.wallets.models.UserWallet
+import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.tap.domain.model.WalletStoreModel
import com.tangem.tap.features.wallet.models.Currency
import kotlinx.coroutines.flow.Flow
diff --git a/app/src/main/java/com/tangem/tap/domain/walletStores/di/WalletsStoresManagerProvider.kt b/app/src/main/java/com/tangem/tap/domain/walletStores/di/WalletsStoresManagerProvider.kt
index d2a4789fb0..d913969cac 100644
--- a/app/src/main/java/com/tangem/tap/domain/walletStores/di/WalletsStoresManagerProvider.kt
+++ b/app/src/main/java/com/tangem/tap/domain/walletStores/di/WalletsStoresManagerProvider.kt
@@ -1,12 +1,12 @@
package com.tangem.tap.domain.walletStores.di
-import com.tangem.tap.domain.walletStores.WalletStoresManager
-import com.tangem.tap.domain.walletStores.implementation.DummyWalletStoresManager
+import com.tangem.domain.wallets.legacy.WalletManagersRepository
import com.tangem.tap.common.entities.FiatCurrency
import com.tangem.tap.domain.tokens.UserTokensRepository
+import com.tangem.tap.domain.walletStores.WalletStoresManager
import com.tangem.tap.domain.walletStores.implementation.DefaultWalletStoresManager
+import com.tangem.tap.domain.walletStores.implementation.DummyWalletStoresManager
import com.tangem.tap.domain.walletStores.repository.WalletAmountsRepository
-import com.tangem.tap.domain.walletStores.repository.WalletManagersRepository
import com.tangem.tap.domain.walletStores.repository.WalletStoresRepository
fun WalletStoresManager.Companion.provideDummyImplementation(): WalletStoresManager {
diff --git a/app/src/main/java/com/tangem/tap/domain/walletStores/implementation/DefaultWalletStoresManager.kt b/app/src/main/java/com/tangem/tap/domain/walletStores/implementation/DefaultWalletStoresManager.kt
index 6081a25788..f2af46b082 100644
--- a/app/src/main/java/com/tangem/tap/domain/walletStores/implementation/DefaultWalletStoresManager.kt
+++ b/app/src/main/java/com/tangem/tap/domain/walletStores/implementation/DefaultWalletStoresManager.kt
@@ -2,22 +2,17 @@ package com.tangem.tap.domain.walletStores.implementation
import com.tangem.blockchain.common.WalletManager
import com.tangem.blockchain.common.address.AddressType
-import com.tangem.common.CompletionResult
-import com.tangem.common.doOnSuccess
-import com.tangem.common.flatMap
-import com.tangem.common.flatMapOnFailure
-import com.tangem.common.fold
-import com.tangem.common.map
-import com.tangem.domain.common.util.UserWalletId
+import com.tangem.common.*
+import com.tangem.domain.wallets.legacy.WalletManagersRepository
+import com.tangem.domain.wallets.models.UserWallet
+import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.tap.common.entities.FiatCurrency
-import com.tangem.tap.domain.model.UserWallet
import com.tangem.tap.domain.model.WalletStoreModel
import com.tangem.tap.domain.model.builders.WalletStoreBuilder
import com.tangem.tap.domain.tokens.UserTokensRepository
import com.tangem.tap.domain.walletStores.WalletStoresError
import com.tangem.tap.domain.walletStores.WalletStoresManager
import com.tangem.tap.domain.walletStores.repository.WalletAmountsRepository
-import com.tangem.tap.domain.walletStores.repository.WalletManagersRepository
import com.tangem.tap.domain.walletStores.repository.WalletStoresRepository
import com.tangem.tap.domain.walletStores.repository.implementation.utils.updateSelectedAddress
import com.tangem.tap.features.wallet.models.Currency
diff --git a/app/src/main/java/com/tangem/tap/domain/walletStores/implementation/DummyWalletStoresManager.kt b/app/src/main/java/com/tangem/tap/domain/walletStores/implementation/DummyWalletStoresManager.kt
index 98fa34d296..9b6ab8abbb 100644
--- a/app/src/main/java/com/tangem/tap/domain/walletStores/implementation/DummyWalletStoresManager.kt
+++ b/app/src/main/java/com/tangem/tap/domain/walletStores/implementation/DummyWalletStoresManager.kt
@@ -2,8 +2,8 @@ package com.tangem.tap.domain.walletStores.implementation
import com.tangem.blockchain.common.address.AddressType
import com.tangem.common.CompletionResult
-import com.tangem.domain.common.util.UserWalletId
-import com.tangem.tap.domain.model.UserWallet
+import com.tangem.domain.wallets.models.UserWallet
+import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.tap.domain.model.WalletStoreModel
import com.tangem.tap.domain.walletStores.WalletStoresManager
import com.tangem.tap.features.wallet.models.Currency
diff --git a/app/src/main/java/com/tangem/tap/domain/walletStores/repository/WalletAmountsRepository.kt b/app/src/main/java/com/tangem/tap/domain/walletStores/repository/WalletAmountsRepository.kt
index 924bbb5191..c25635dd50 100644
--- a/app/src/main/java/com/tangem/tap/domain/walletStores/repository/WalletAmountsRepository.kt
+++ b/app/src/main/java/com/tangem/tap/domain/walletStores/repository/WalletAmountsRepository.kt
@@ -1,8 +1,8 @@
package com.tangem.tap.domain.walletStores.repository
import com.tangem.common.CompletionResult
+import com.tangem.domain.wallets.models.UserWallet
import com.tangem.tap.common.entities.FiatCurrency
-import com.tangem.tap.domain.model.UserWallet
import com.tangem.tap.domain.model.WalletStoreModel
interface WalletAmountsRepository {
diff --git a/app/src/main/java/com/tangem/tap/domain/walletStores/repository/WalletStoresRepository.kt b/app/src/main/java/com/tangem/tap/domain/walletStores/repository/WalletStoresRepository.kt
index ad80694e1e..6007fcb2c3 100644
--- a/app/src/main/java/com/tangem/tap/domain/walletStores/repository/WalletStoresRepository.kt
+++ b/app/src/main/java/com/tangem/tap/domain/walletStores/repository/WalletStoresRepository.kt
@@ -1,7 +1,7 @@
package com.tangem.tap.domain.walletStores.repository
import com.tangem.common.CompletionResult
-import com.tangem.domain.common.util.UserWalletId
+import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.tap.domain.model.WalletStoreModel
import com.tangem.tap.features.wallet.models.Currency
import kotlinx.coroutines.flow.Flow
diff --git a/app/src/main/java/com/tangem/tap/domain/walletStores/repository/di/RepositoryProvider.kt b/app/src/main/java/com/tangem/tap/domain/walletStores/repository/di/RepositoryProvider.kt
index d89d4ea6aa..769a1e0219 100644
--- a/app/src/main/java/com/tangem/tap/domain/walletStores/repository/di/RepositoryProvider.kt
+++ b/app/src/main/java/com/tangem/tap/domain/walletStores/repository/di/RepositoryProvider.kt
@@ -2,8 +2,8 @@ package com.tangem.tap.domain.walletStores.repository.di
import com.tangem.blockchain.common.WalletManagerFactory
import com.tangem.datasource.api.tangemTech.TangemTechService
+import com.tangem.domain.wallets.legacy.WalletManagersRepository
import com.tangem.tap.domain.walletStores.repository.WalletAmountsRepository
-import com.tangem.tap.domain.walletStores.repository.WalletManagersRepository
import com.tangem.tap.domain.walletStores.repository.WalletStoresRepository
import com.tangem.tap.domain.walletStores.repository.implementation.DefaultWalletAmountsRepository
import com.tangem.tap.domain.walletStores.repository.implementation.DefaultWalletManagersRepository
diff --git a/app/src/main/java/com/tangem/tap/domain/walletStores/repository/implementation/DefaultWalletAmountsRepository.kt b/app/src/main/java/com/tangem/tap/domain/walletStores/repository/implementation/DefaultWalletAmountsRepository.kt
index 22dd64bff1..b89be4b97f 100644
--- a/app/src/main/java/com/tangem/tap/domain/walletStores/repository/implementation/DefaultWalletAmountsRepository.kt
+++ b/app/src/main/java/com/tangem/tap/domain/walletStores/repository/implementation/DefaultWalletAmountsRepository.kt
@@ -10,13 +10,13 @@ import com.tangem.blockchain.extensions.Result.Success
import com.tangem.common.*
import com.tangem.common.core.TangemError
import com.tangem.datasource.api.tangemTech.TangemTechApi
-import com.tangem.domain.common.util.UserWalletId
import com.tangem.domain.common.util.hasDerivation
import com.tangem.domain.models.scan.ScanResponse
+import com.tangem.domain.wallets.models.UserWallet
+import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.tap.common.TestActions
import com.tangem.tap.common.entities.FiatCurrency
import com.tangem.tap.common.extensions.replaceByOrAdd
-import com.tangem.tap.domain.model.UserWallet
import com.tangem.tap.domain.model.WalletStoreModel
import com.tangem.tap.domain.walletStores.WalletStoresError
import com.tangem.tap.domain.walletStores.repository.WalletAmountsRepository
@@ -169,7 +169,7 @@ internal class DefaultWalletAmountsRepository(
walletStores.map { walletStore ->
async {
- // TODO: Find wallet manager via [com.tangem.tap.domain.walletStores.repository.WalletManagersRepository]
+ // TODO: Find wallet manager via [com.tangem.domain.wallets.legacy.WalletManagersRepository]
val walletManager = walletStore.walletManager
fetchAmountsForWalletStore(userWalletId, scanResponse, walletStore, walletManager)
}
diff --git a/app/src/main/java/com/tangem/tap/domain/walletStores/repository/implementation/DefaultWalletManagersRepository.kt b/app/src/main/java/com/tangem/tap/domain/walletStores/repository/implementation/DefaultWalletManagersRepository.kt
index b2d8167a7e..7a51a18e10 100644
--- a/app/src/main/java/com/tangem/tap/domain/walletStores/repository/implementation/DefaultWalletManagersRepository.kt
+++ b/app/src/main/java/com/tangem/tap/domain/walletStores/repository/implementation/DefaultWalletManagersRepository.kt
@@ -1,27 +1,22 @@
package com.tangem.tap.domain.walletStores.repository.implementation
-import com.tangem.blockchain.common.Amount
-import com.tangem.blockchain.common.Blockchain
-import com.tangem.blockchain.common.DerivationParams
-import com.tangem.blockchain.common.DerivationStyle
-import com.tangem.blockchain.common.WalletManager
-import com.tangem.blockchain.common.WalletManagerFactory
+import com.tangem.blockchain.common.*
import com.tangem.common.CompletionResult
import com.tangem.common.catching
import com.tangem.common.doOnSuccess
import com.tangem.common.mapFailure
import com.tangem.crypto.hdWallet.DerivationPath
+import com.tangem.domain.common.BlockchainNetwork
import com.tangem.domain.common.TapWorkarounds.isTestCard
import com.tangem.domain.common.TapWorkarounds.useOldStyleDerivation
import com.tangem.domain.common.util.cardTypesResolver
-import com.tangem.domain.common.util.UserWalletId
import com.tangem.domain.models.scan.CardDTO
import com.tangem.domain.models.scan.ScanResponse
+import com.tangem.domain.wallets.legacy.WalletManagersRepository
+import com.tangem.domain.wallets.models.UserWallet
+import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.tap.domain.extensions.makeWalletManagerForApp
-import com.tangem.tap.domain.model.UserWallet
-import com.tangem.tap.domain.tokens.models.BlockchainNetwork
import com.tangem.tap.domain.walletStores.WalletStoresError
-import com.tangem.tap.domain.walletStores.repository.WalletManagersRepository
import com.tangem.tap.domain.walletStores.storage.WalletManagerStorage
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.firstOrNull
diff --git a/app/src/main/java/com/tangem/tap/domain/walletStores/repository/implementation/DefaultWalletStoresRepository.kt b/app/src/main/java/com/tangem/tap/domain/walletStores/repository/implementation/DefaultWalletStoresRepository.kt
index 89997208ba..fb78960bb1 100644
--- a/app/src/main/java/com/tangem/tap/domain/walletStores/repository/implementation/DefaultWalletStoresRepository.kt
+++ b/app/src/main/java/com/tangem/tap/domain/walletStores/repository/implementation/DefaultWalletStoresRepository.kt
@@ -2,7 +2,7 @@ package com.tangem.tap.domain.walletStores.repository.implementation
import com.tangem.common.CompletionResult
import com.tangem.common.catching
-import com.tangem.domain.common.util.UserWalletId
+import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.tap.domain.model.WalletStoreModel
import com.tangem.tap.domain.walletStores.repository.WalletStoresRepository
import com.tangem.tap.domain.walletStores.repository.implementation.utils.isSameWalletStore
diff --git a/app/src/main/java/com/tangem/tap/domain/walletStores/repository/implementation/utils/WalletStoreOperations.kt b/app/src/main/java/com/tangem/tap/domain/walletStores/repository/implementation/utils/WalletStoreOperations.kt
index 069f77fe4b..bc6c07563d 100644
--- a/app/src/main/java/com/tangem/tap/domain/walletStores/repository/implementation/utils/WalletStoreOperations.kt
+++ b/app/src/main/java/com/tangem/tap/domain/walletStores/repository/implementation/utils/WalletStoreOperations.kt
@@ -3,7 +3,7 @@ package com.tangem.tap.domain.walletStores.repository.implementation.utils
import com.tangem.blockchain.common.Wallet
import com.tangem.blockchain.common.address.AddressType
import com.tangem.common.core.TangemError
-import com.tangem.domain.common.util.UserWalletId
+import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.tap.domain.model.WalletStoreModel
import com.tangem.tap.features.wallet.models.Currency
import timber.log.Timber
diff --git a/app/src/main/java/com/tangem/tap/domain/walletStores/storage/WalletManagerStorage.kt b/app/src/main/java/com/tangem/tap/domain/walletStores/storage/WalletManagerStorage.kt
index 866711e543..3d492d01da 100644
--- a/app/src/main/java/com/tangem/tap/domain/walletStores/storage/WalletManagerStorage.kt
+++ b/app/src/main/java/com/tangem/tap/domain/walletStores/storage/WalletManagerStorage.kt
@@ -1,7 +1,7 @@
package com.tangem.tap.domain.walletStores.storage
import com.tangem.blockchain.common.WalletManager
-import com.tangem.domain.common.util.UserWalletId
+import com.tangem.domain.wallets.models.UserWalletId
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
diff --git a/app/src/main/java/com/tangem/tap/domain/walletStores/storage/WalletStoresStorage.kt b/app/src/main/java/com/tangem/tap/domain/walletStores/storage/WalletStoresStorage.kt
index 932abce88b..883783db86 100644
--- a/app/src/main/java/com/tangem/tap/domain/walletStores/storage/WalletStoresStorage.kt
+++ b/app/src/main/java/com/tangem/tap/domain/walletStores/storage/WalletStoresStorage.kt
@@ -1,6 +1,6 @@
package com.tangem.tap.domain.walletStores.storage
-import com.tangem.domain.common.util.UserWalletId
+import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.tap.domain.model.WalletStoreModel
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableSharedFlow
diff --git a/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectManager.kt b/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectManager.kt
index 7b80ce1039..4ba9c2f058 100644
--- a/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectManager.kt
+++ b/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectManager.kt
@@ -394,7 +394,7 @@ class WalletConnectManager {
),
)
}
- Analytics.send(WalletConnect.NewSessionEstablished())
+ Analytics.send(WalletConnect.NewSessionEstablished(""))
}
}
}
diff --git a/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectSdkHelper.kt b/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectSdkHelper.kt
index dc3169c18c..134a915fbd 100644
--- a/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectSdkHelper.kt
+++ b/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectSdkHelper.kt
@@ -16,6 +16,7 @@ import com.tangem.common.extensions.hexToBytes
import com.tangem.common.extensions.toDecompressedPublicKey
import com.tangem.common.extensions.toHexString
import com.tangem.core.analytics.Analytics
+import com.tangem.domain.common.BlockchainNetwork
import com.tangem.domain.common.extensions.fromNetworkId
import com.tangem.operations.sign.SignHashCommand
import com.tangem.tap.common.analytics.events.AnalyticsParam
@@ -24,7 +25,6 @@ import com.tangem.tap.common.analytics.events.Basic.TransactionSent.MemoType
import com.tangem.tap.common.analytics.events.WalletConnect
import com.tangem.tap.common.extensions.safeUpdate
import com.tangem.tap.common.extensions.toFormattedString
-import com.tangem.tap.domain.tokens.models.BlockchainNetwork
import com.tangem.tap.domain.walletconnect.BnbHelper.toWCBinanceTradeOrder
import com.tangem.tap.domain.walletconnect.BnbHelper.toWCBinanceTransferOrder
import com.tangem.tap.domain.walletconnect2.domain.WcEthereumSignMessage
diff --git a/app/src/main/java/com/tangem/tap/domain/walletconnect2/data/WalletConnectRepositoryImpl.kt b/app/src/main/java/com/tangem/tap/domain/walletconnect2/data/WalletConnectRepositoryImpl.kt
index 12c5510122..dcd79b0985 100644
--- a/app/src/main/java/com/tangem/tap/domain/walletconnect2/data/WalletConnectRepositoryImpl.kt
+++ b/app/src/main/java/com/tangem/tap/domain/walletconnect2/data/WalletConnectRepositoryImpl.kt
@@ -2,6 +2,8 @@ package com.tangem.tap.domain.walletconnect2.data
import android.app.Application
import arrow.core.flatten
+import com.tangem.core.analytics.Analytics
+import com.tangem.tap.common.analytics.events.WalletConnect
import com.tangem.tap.domain.walletconnect2.domain.WalletConnectRepository
import com.tangem.tap.domain.walletconnect2.domain.WcJrpcRequestsDeserializer
import com.tangem.tap.domain.walletconnect2.domain.models.*
@@ -237,6 +239,7 @@ class WalletConnectRepositoryImpl @Inject constructor(
params = sessionApproval,
onSuccess = {
Timber.d("Approved successfully: $it")
+ Analytics.send(WalletConnect.NewSessionEstablished(sessionProposal.name))
},
onError = {
Timber.d("Error while approving: $it")
@@ -261,7 +264,9 @@ class WalletConnectRepositoryImpl @Inject constructor(
),
),
onSuccess = {},
- onError = {},
+ onError = {
+ Analytics.send(WalletConnect.TransactionError(it.throwable))
+ },
)
}
@@ -299,6 +304,7 @@ class WalletConnectRepositoryImpl @Inject constructor(
Web3Wallet.disconnectSession(
params = Wallet.Params.SessionDisconnect(topic),
onSuccess = {
+ Analytics.send(WalletConnect.SessionDisconnected())
updateSessions()
Timber.d("Disconnected successfully: $it")
},
diff --git a/app/src/main/java/com/tangem/tap/domain/walletconnect2/domain/WalletConnectInteractor.kt b/app/src/main/java/com/tangem/tap/domain/walletconnect2/domain/WalletConnectInteractor.kt
index 7d929df9fc..5bd6d8f0a1 100644
--- a/app/src/main/java/com/tangem/tap/domain/walletconnect2/domain/WalletConnectInteractor.kt
+++ b/app/src/main/java/com/tangem/tap/domain/walletconnect2/domain/WalletConnectInteractor.kt
@@ -1,5 +1,7 @@
package com.tangem.tap.domain.walletconnect2.domain
+import com.tangem.core.analytics.Analytics
+import com.tangem.tap.common.analytics.events.WalletConnect
import com.tangem.tap.common.extensions.filterNotNull
import com.tangem.tap.domain.walletconnect.WalletConnectSdkHelper
import com.tangem.tap.domain.walletconnect2.domain.models.*
@@ -216,6 +218,7 @@ class WalletConnectInteractor(
id = request.requestId,
)
} else {
+ Analytics.send(WalletConnect.RequestSigned())
walletConnectRepository.sendRequest(
topic = request.topic,
id = request.requestId,
diff --git a/app/src/main/java/com/tangem/tap/features/BaseFragment.kt b/app/src/main/java/com/tangem/tap/features/BaseFragment.kt
index cf8be74484..cddf55cc07 100644
--- a/app/src/main/java/com/tangem/tap/features/BaseFragment.kt
+++ b/app/src/main/java/com/tangem/tap/features/BaseFragment.kt
@@ -14,7 +14,7 @@ import androidx.lifecycle.Lifecycle
import androidx.transition.TransitionInflater
import com.google.android.material.snackbar.Snackbar
import com.tangem.common.extensions.VoidCallback
-import com.tangem.tap.common.redux.navigation.NavigationAction
+import com.tangem.core.navigation.NavigationAction
import com.tangem.tap.store
import com.tangem.wallet.R
diff --git a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/routers/DefaultCustomTokenRouter.kt b/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/routers/DefaultCustomTokenRouter.kt
index 25eb163e9b..7afec7d5a5 100644
--- a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/routers/DefaultCustomTokenRouter.kt
+++ b/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/routers/DefaultCustomTokenRouter.kt
@@ -1,7 +1,7 @@
package com.tangem.tap.features.customtoken.impl.presentation.routers
-import com.tangem.tap.common.redux.navigation.AppScreen
-import com.tangem.tap.common.redux.navigation.NavigationAction
+import com.tangem.core.navigation.AppScreen
+import com.tangem.core.navigation.NavigationAction
import com.tangem.tap.store
/** Default implementation of custom token feature router */
diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt
index acc0130ea9..a992489911 100644
--- a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt
+++ b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt
@@ -7,9 +7,12 @@ import com.tangem.common.doOnSuccess
import com.tangem.common.extensions.guard
import com.tangem.common.flatMap
import com.tangem.core.analytics.Analytics
+import com.tangem.core.navigation.AppScreen
+import com.tangem.core.navigation.NavigationAction
import com.tangem.domain.common.TapWorkarounds.isTangemTwins
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.domain.models.scan.ScanResponse
+import com.tangem.domain.wallets.legacy.UserWalletsListManager
import com.tangem.tap.*
import com.tangem.tap.common.analytics.events.AnalyticsParam
import com.tangem.tap.common.analytics.events.Settings
@@ -20,12 +23,9 @@ import com.tangem.tap.common.extensions.onUserWalletSelected
import com.tangem.tap.common.redux.AppDialog
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.common.redux.global.GlobalAction
-import com.tangem.tap.common.redux.navigation.AppScreen
-import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.domain.model.builders.UserWalletBuilder
import com.tangem.tap.domain.model.builders.UserWalletIdBuilder
import com.tangem.tap.domain.scanCard.ScanCardProcessor
-import com.tangem.tap.domain.userWalletList.UserWalletsListManager
import com.tangem.tap.domain.userWalletList.di.provideBiometricImplementation
import com.tangem.tap.domain.userWalletList.di.provideRuntimeImplementation
import com.tangem.tap.domain.userWalletList.isLockedSync
@@ -33,13 +33,7 @@ import com.tangem.tap.features.demo.DemoHelper
import com.tangem.tap.features.onboarding.products.twins.redux.CreateTwinWalletMode
import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsAction
import com.tangem.tap.features.wallet.redux.WalletAction
-import com.tangem.tap.foregroundActivityObserver
-import com.tangem.tap.preferencesStorage
-import com.tangem.tap.scope
-import com.tangem.tap.store
import com.tangem.tap.tangemSdkManager
-import com.tangem.tap.userWalletsListManager
-import com.tangem.tap.walletStoresManager
import com.tangem.wallet.R
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectMiddleware.kt b/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectMiddleware.kt
index b69de63a66..802ad1b140 100644
--- a/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectMiddleware.kt
+++ b/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectMiddleware.kt
@@ -4,6 +4,9 @@ import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.DerivationStyle
import com.tangem.blockchain.common.WalletManager
import com.tangem.common.extensions.guard
+import com.tangem.core.navigation.AppScreen
+import com.tangem.core.navigation.NavigationAction
+import com.tangem.domain.common.BlockchainNetwork
import com.tangem.domain.common.TapWorkarounds.derivationStyle
import com.tangem.domain.common.extensions.fromNetworkId
import com.tangem.domain.common.extensions.toNetworkId
@@ -14,9 +17,6 @@ import com.tangem.domain.models.scan.ScanResponse
import com.tangem.tap.common.extensions.dispatchOnMain
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.common.redux.global.GlobalAction
-import com.tangem.tap.common.redux.navigation.AppScreen
-import com.tangem.tap.common.redux.navigation.NavigationAction
-import com.tangem.tap.domain.tokens.models.BlockchainNetwork
import com.tangem.tap.domain.walletconnect.BnbHelper
import com.tangem.tap.domain.walletconnect.WalletConnectManager
import com.tangem.tap.domain.walletconnect.WalletConnectNetworkUtils
diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/AppSettingsFragment.kt b/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/AppSettingsFragment.kt
index 5ced6c832e..0f0e3de308 100644
--- a/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/AppSettingsFragment.kt
+++ b/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/AppSettingsFragment.kt
@@ -9,8 +9,8 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.platform.ComposeView
import androidx.fragment.app.Fragment
import androidx.transition.TransitionInflater
+import com.tangem.core.navigation.NavigationAction
import com.tangem.core.ui.res.TangemTheme
-import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.features.details.redux.DetailsAction
import com.tangem.tap.features.details.redux.DetailsState
import com.tangem.tap.store
diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/cardsettings/CardSettingsFragment.kt b/app/src/main/java/com/tangem/tap/features/details/ui/cardsettings/CardSettingsFragment.kt
index e67d9b5adf..90c489ab41 100644
--- a/app/src/main/java/com/tangem/tap/features/details/ui/cardsettings/CardSettingsFragment.kt
+++ b/app/src/main/java/com/tangem/tap/features/details/ui/cardsettings/CardSettingsFragment.kt
@@ -9,8 +9,8 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.platform.ComposeView
import androidx.fragment.app.Fragment
import androidx.transition.TransitionInflater
+import com.tangem.core.navigation.NavigationAction
import com.tangem.core.ui.res.TangemTheme
-import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.features.details.redux.DetailsAction
import com.tangem.tap.features.details.redux.DetailsState
import com.tangem.tap.store
diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/cardsettings/coderecovery/AccessCodeRecoveryFragment.kt b/app/src/main/java/com/tangem/tap/features/details/ui/cardsettings/coderecovery/AccessCodeRecoveryFragment.kt
index 370d333d31..cb50141a2c 100644
--- a/app/src/main/java/com/tangem/tap/features/details/ui/cardsettings/coderecovery/AccessCodeRecoveryFragment.kt
+++ b/app/src/main/java/com/tangem/tap/features/details/ui/cardsettings/coderecovery/AccessCodeRecoveryFragment.kt
@@ -9,8 +9,8 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.platform.ComposeView
import androidx.fragment.app.Fragment
import androidx.transition.TransitionInflater
+import com.tangem.core.navigation.NavigationAction
import com.tangem.core.ui.res.TangemTheme
-import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.features.details.redux.DetailsState
import com.tangem.tap.store
import com.tangem.wallet.R
diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/details/DetailsFragment.kt b/app/src/main/java/com/tangem/tap/features/details/ui/details/DetailsFragment.kt
index 3c37bacd20..371b571cdd 100644
--- a/app/src/main/java/com/tangem/tap/features/details/ui/details/DetailsFragment.kt
+++ b/app/src/main/java/com/tangem/tap/features/details/ui/details/DetailsFragment.kt
@@ -8,11 +8,12 @@ import androidx.compose.ui.platform.ComposeView
import androidx.fragment.app.Fragment
import androidx.transition.TransitionInflater
import com.tangem.core.analytics.Analytics
+import com.tangem.core.navigation.NavigationAction
import com.tangem.core.ui.res.TangemTheme
import com.tangem.tap.common.analytics.events.Settings
-import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.features.details.redux.DetailsState
import com.tangem.tap.store
+import com.tangem.wallet.R
import org.rekotlin.StoreSubscriber
class DetailsFragment : Fragment(), StoreSubscriber {
@@ -23,8 +24,8 @@ class DetailsFragment : Fragment(), StoreSubscriber {
super.onCreate(savedInstanceState)
Analytics.send(Settings.ScreenOpened())
val inflater = TransitionInflater.from(requireContext())
- enterTransition = inflater.inflateTransition(android.R.transition.fade)
- exitTransition = inflater.inflateTransition(android.R.transition.fade)
+ enterTransition = inflater.inflateTransition(R.transition.fade)
+ exitTransition = inflater.inflateTransition(R.transition.fade)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/details/DetailsViewModel.kt b/app/src/main/java/com/tangem/tap/features/details/ui/details/DetailsViewModel.kt
index e9766c6147..8301791338 100644
--- a/app/src/main/java/com/tangem/tap/features/details/ui/details/DetailsViewModel.kt
+++ b/app/src/main/java/com/tangem/tap/features/details/ui/details/DetailsViewModel.kt
@@ -3,14 +3,14 @@ package com.tangem.tap.features.details.ui.details
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import com.tangem.core.analytics.Analytics
+import com.tangem.core.navigation.AppScreen
+import com.tangem.core.navigation.NavigationAction
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.tap.common.analytics.events.Settings
import com.tangem.tap.common.feedback.FeedbackEmail
import com.tangem.tap.common.feedback.SupportInfo
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.common.redux.global.GlobalAction
-import com.tangem.tap.common.redux.navigation.AppScreen
-import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.features.details.redux.DetailsState
import com.tangem.tap.features.disclaimer.redux.DisclaimerAction
import com.tangem.tap.features.home.LocaleRegionProvider
diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/resetcard/ResetCardFragment.kt b/app/src/main/java/com/tangem/tap/features/details/ui/resetcard/ResetCardFragment.kt
index df48063920..7a7c723779 100644
--- a/app/src/main/java/com/tangem/tap/features/details/ui/resetcard/ResetCardFragment.kt
+++ b/app/src/main/java/com/tangem/tap/features/details/ui/resetcard/ResetCardFragment.kt
@@ -9,8 +9,8 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.platform.ComposeView
import androidx.fragment.app.Fragment
import androidx.transition.TransitionInflater
+import com.tangem.core.navigation.NavigationAction
import com.tangem.core.ui.res.TangemTheme
-import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.features.details.redux.DetailsState
import com.tangem.tap.store
import org.rekotlin.StoreSubscriber
diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/securitymode/SecurityModeFragment.kt b/app/src/main/java/com/tangem/tap/features/details/ui/securitymode/SecurityModeFragment.kt
index 77eb446ad1..c3b2015297 100644
--- a/app/src/main/java/com/tangem/tap/features/details/ui/securitymode/SecurityModeFragment.kt
+++ b/app/src/main/java/com/tangem/tap/features/details/ui/securitymode/SecurityModeFragment.kt
@@ -9,8 +9,8 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.platform.ComposeView
import androidx.fragment.app.Fragment
import androidx.transition.TransitionInflater
+import com.tangem.core.navigation.NavigationAction
import com.tangem.core.ui.res.TangemTheme
-import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.features.details.redux.DetailsState
import com.tangem.tap.store
import org.rekotlin.StoreSubscriber
diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/QrScanFragment.kt b/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/QrScanFragment.kt
index 91a8e803b3..d67c7a262d 100644
--- a/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/QrScanFragment.kt
+++ b/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/QrScanFragment.kt
@@ -13,7 +13,7 @@ import androidx.core.view.WindowCompat
import androidx.fragment.app.Fragment
import com.google.zxing.Result
import com.otaliastudios.cameraview.CameraView
-import com.tangem.tap.common.redux.navigation.NavigationAction
+import com.tangem.core.navigation.NavigationAction
import com.tangem.tap.features.details.redux.walletconnect.WalletConnectAction
import com.tangem.tap.store
import me.dm7.barcodescanner.zxing.ZXingScannerView
diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/WalletConnectFragment.kt b/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/WalletConnectFragment.kt
index 4d5354e3f4..2c7ebdea6e 100644
--- a/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/WalletConnectFragment.kt
+++ b/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/WalletConnectFragment.kt
@@ -10,9 +10,9 @@ import androidx.compose.ui.platform.ComposeView
import androidx.fragment.app.Fragment
import androidx.transition.TransitionInflater
import com.tangem.core.analytics.Analytics
+import com.tangem.core.navigation.NavigationAction
import com.tangem.core.ui.res.TangemTheme
import com.tangem.tap.common.analytics.events.WalletConnect
-import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.features.details.redux.walletconnect.WalletConnectAction
import com.tangem.tap.features.details.redux.walletconnect.WalletConnectState
import com.tangem.tap.store
diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/ClipboardOrScanQrDialog.kt b/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/ClipboardOrScanQrDialog.kt
index d1962be5e4..a3f94a3cd9 100644
--- a/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/ClipboardOrScanQrDialog.kt
+++ b/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/ClipboardOrScanQrDialog.kt
@@ -2,9 +2,9 @@ package com.tangem.tap.features.details.ui.walletconnect.dialogs
import android.content.Context
import androidx.appcompat.app.AlertDialog
+import com.tangem.core.navigation.AppScreen
+import com.tangem.core.navigation.NavigationAction
import com.tangem.tap.common.redux.global.GlobalAction
-import com.tangem.tap.common.redux.navigation.AppScreen
-import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.features.details.redux.walletconnect.WalletConnectAction
import com.tangem.tap.store
import com.tangem.wallet.R
diff --git a/app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerAction.kt b/app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerAction.kt
index 1a712e1c49..ded89f039b 100644
--- a/app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerAction.kt
+++ b/app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerAction.kt
@@ -1,6 +1,6 @@
package com.tangem.tap.features.disclaimer.redux
-import com.tangem.tap.common.redux.navigation.AppScreen
+import com.tangem.core.navigation.AppScreen
import com.tangem.tap.features.disclaimer.Disclaimer
import com.tangem.tap.features.wallet.redux.ProgressState
import org.rekotlin.Action
diff --git a/app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerMiddleware.kt b/app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerMiddleware.kt
index ca71193f2a..e71184aff2 100644
--- a/app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerMiddleware.kt
+++ b/app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerMiddleware.kt
@@ -1,8 +1,8 @@
package com.tangem.tap.features.disclaimer.redux
+import com.tangem.core.navigation.AppScreen
+import com.tangem.core.navigation.NavigationAction
import com.tangem.tap.common.redux.AppState
-import com.tangem.tap.common.redux.navigation.AppScreen
-import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.store
import org.rekotlin.Action
import org.rekotlin.Middleware
diff --git a/app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerState.kt b/app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerState.kt
index b610475974..ff9ab50f31 100644
--- a/app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerState.kt
+++ b/app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerState.kt
@@ -1,7 +1,7 @@
package com.tangem.tap.features.disclaimer.redux
import com.tangem.common.extensions.VoidCallback
-import com.tangem.tap.common.redux.navigation.AppScreen
+import com.tangem.core.navigation.AppScreen
import com.tangem.tap.features.disclaimer.Disclaimer
import com.tangem.tap.features.disclaimer.DummyDisclaimer
import com.tangem.tap.features.wallet.redux.ProgressState
diff --git a/app/src/main/java/com/tangem/tap/features/disclaimer/ui/DisclaimerFragment.kt b/app/src/main/java/com/tangem/tap/features/disclaimer/ui/DisclaimerFragment.kt
index c54f4ff005..ab1ec2715d 100644
--- a/app/src/main/java/com/tangem/tap/features/disclaimer/ui/DisclaimerFragment.kt
+++ b/app/src/main/java/com/tangem/tap/features/disclaimer/ui/DisclaimerFragment.kt
@@ -6,12 +6,12 @@ import android.view.View.OVER_SCROLL_NEVER
import android.webkit.WebView
import androidx.transition.TransitionInflater
import by.kirich1409.viewbindingdelegate.viewBinding
+import com.tangem.core.navigation.AppScreen
import com.tangem.core.ui.fragments.setStatusBarColor
import com.tangem.tap.common.extensions.beginDelayedTransition
import com.tangem.tap.common.extensions.hide
import com.tangem.tap.common.extensions.show
import com.tangem.tap.common.redux.AppState
-import com.tangem.tap.common.redux.navigation.AppScreen
import com.tangem.tap.features.BaseFragment
import com.tangem.tap.features.addBackPressHandler
import com.tangem.tap.features.disclaimer.Disclaimer
diff --git a/app/src/main/java/com/tangem/tap/features/home/HomeFragment.kt b/app/src/main/java/com/tangem/tap/features/home/HomeFragment.kt
index acf3408acf..e4885e7314 100644
--- a/app/src/main/java/com/tangem/tap/features/home/HomeFragment.kt
+++ b/app/src/main/java/com/tangem/tap/features/home/HomeFragment.kt
@@ -12,36 +12,47 @@ import androidx.compose.ui.platform.ComposeView
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsControllerCompat
import androidx.fragment.app.Fragment
-import com.google.accompanist.appcompattheme.AppCompatTheme
+import androidx.fragment.app.activityViewModels
import com.tangem.core.analytics.Analytics
+import com.tangem.core.navigation.AppScreen
+import com.tangem.core.navigation.NavigationAction
+import com.tangem.core.ui.res.TangemTheme
+import com.tangem.feature.learn2earn.presentation.Learn2earnViewModel
import com.tangem.tap.common.analytics.events.IntroductionProcess
-import com.tangem.tap.common.redux.navigation.AppScreen
-import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.features.home.compose.StoriesScreen
import com.tangem.tap.features.home.redux.HomeAction
import com.tangem.tap.features.home.redux.HomeState
+import com.tangem.tap.features.home.redux.Stories
import com.tangem.tap.features.tokens.legacy.redux.TokensAction
import com.tangem.tap.store
+import dagger.hilt.android.AndroidEntryPoint
import org.rekotlin.StoreSubscriber
+@AndroidEntryPoint
class HomeFragment : Fragment(), StoreSubscriber {
private var homeState: MutableState = mutableStateOf(store.state.homeState)
+ private val learn2earnViewModel by activityViewModels()
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
store.dispatch(HomeAction.OnCreate)
store.dispatch(HomeAction.Init)
+ if (learn2earnViewModel.uiState.storyScreenState.isVisible) {
+ store.dispatch(HomeAction.InsertStory(position = 0, Stories.OneInchPromo))
+ // re init homeState after inserting learn2earn story
+ homeState = mutableStateOf(store.state.homeState)
+ }
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
return ComposeView(inflater.context).apply {
setContent {
- BackHandler {
- requireActivity().finish()
- }
-
- AppCompatTheme {
+ TangemTheme {
+ BackHandler {
+ requireActivity().finish()
+ }
ScreenContent()
}
}
@@ -79,7 +90,8 @@ class HomeFragment : Fragment(), StoreSubscriber {
@Composable
private fun ScreenContent() {
StoriesScreen(
- homeState,
+ homeState = homeState,
+ onLearn2earnClick = learn2earnViewModel.uiState.storyScreenState.onClick,
onScanButtonClick = {
Analytics.send(IntroductionProcess.ButtonScanCard())
store.dispatch(HomeAction.ReadCard())
diff --git a/app/src/main/java/com/tangem/tap/features/home/compose/StoriesScreen.kt b/app/src/main/java/com/tangem/tap/features/home/compose/StoriesScreen.kt
index ef40d850f6..fa3e832436 100644
--- a/app/src/main/java/com/tangem/tap/features/home/compose/StoriesScreen.kt
+++ b/app/src/main/java/com/tangem/tap/features/home/compose/StoriesScreen.kt
@@ -5,29 +5,11 @@ package com.tangem.tap.features.home.compose
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.detectTapGestures
-import androidx.compose.foundation.layout.Arrangement
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.WindowInsets
-import androidx.compose.foundation.layout.fillMaxHeight
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.height
-import androidx.compose.foundation.layout.heightIn
-import androidx.compose.foundation.layout.navigationBarsPadding
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.statusBars
-import androidx.compose.foundation.layout.union
-import androidx.compose.foundation.layout.windowInsetsPadding
+import androidx.compose.foundation.layout.*
import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.Text
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.LaunchedEffect
-import androidx.compose.runtime.MutableState
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
+import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
@@ -43,38 +25,40 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.google.accompanist.systemuicontroller.rememberSystemUiController
-import com.tangem.tap.features.home.compose.content.FirstStoriesContent
-import com.tangem.tap.features.home.compose.content.StoriesCurrencies
-import com.tangem.tap.features.home.compose.content.StoriesRevolutionaryWallet
-import com.tangem.tap.features.home.compose.content.StoriesUltraSecureBackup
-import com.tangem.tap.features.home.compose.content.StoriesWalletForEveryone
-import com.tangem.tap.features.home.compose.content.StoriesWeb3
+import com.tangem.core.ui.res.TangemTheme
+import com.tangem.feature.learn2earn.presentation.ui.Learn2earnStoriesScreen
+import com.tangem.tap.features.home.compose.content.*
import com.tangem.tap.features.home.compose.views.HomeButtons
import com.tangem.tap.features.home.compose.views.StoriesProgressBar
import com.tangem.tap.features.home.redux.HomeState
+import com.tangem.tap.features.home.redux.Stories
import com.tangem.wallet.R
import kotlin.math.max
-private const val STEPS = 6
-
@Suppress("LongMethod", "ComplexMethod")
@Composable
fun StoriesScreen(
homeState: MutableState,
+ onLearn2earnClick: () -> Unit,
onScanButtonClick: () -> Unit,
onShopButtonClick: () -> Unit,
onSearchTokensClick: () -> Unit,
) {
- val currentStep = remember { mutableStateOf(1) }
val systemUiController = rememberSystemUiController()
+ val state = homeState.value
- val isDarkBackground = currentStep.value !in 3..5
+ var currentStory by remember { mutableStateOf(state.firstStory) }
+ val currentStep = { state.stepOf(currentStory) }
val goToPreviousScreen = {
- currentStep.value = max(1, currentStep.value - 1)
+ currentStory = state.stories[max(0, currentStep() - 1)]
}
val goToNextScreen = {
- currentStep.value = if (currentStep.value < STEPS) currentStep.value + 1 else 1
+ currentStory = if (currentStep() < state.stories.lastIndex) {
+ state.stories[currentStep() + 1]
+ } else {
+ state.firstStory
+ }
}
val isPressed = remember { mutableStateOf(false) }
@@ -82,10 +66,10 @@ fun StoriesScreen(
val hideContent = remember { mutableStateOf(true) }
- LaunchedEffect(key1 = isDarkBackground) {
+ LaunchedEffect(key1 = currentStory.isDarkBackground) {
systemUiController.setSystemBarsColor(
color = Color.Transparent,
- darkIcons = !isDarkBackground,
+ darkIcons = !currentStory.isDarkBackground,
)
}
@@ -134,7 +118,7 @@ fun StoriesScreen(
},
)
}
- if (!isDarkBackground) {
+ if (!currentStory.isDarkBackground) {
Image(
modifier = Modifier.fillMaxSize(),
painter = painterResource(id = R.drawable.ic_overlay),
@@ -154,9 +138,9 @@ fun StoriesScreen(
verticalArrangement = Arrangement.Center,
) {
StoriesProgressBar(
- steps = STEPS,
- currentStep = currentStep.value,
- stepDuration = currentStep.duration(),
+ steps = state.stories.lastIndex,
+ currentStep = currentStep(),
+ stepDuration = currentStory.duration,
paused = isPaused,
onStepFinish = goToNextScreen,
)
@@ -169,15 +153,16 @@ fun StoriesScreen(
.height(17.dp)
.alpha(if (hideContent.value) 0f else 1f)
.align(Alignment.Start),
- colorFilter = if (isDarkBackground) null else ColorFilter.tint(Color.Black),
+ colorFilter = if (currentStory.isDarkBackground) null else ColorFilter.tint(Color.Black),
)
- when (currentStep.value) {
- 1 -> FirstStoriesContent(isPaused, currentStep.duration()) { hideContent.value = it }
- 2 -> StoriesRevolutionaryWallet(currentStep.duration())
- 3 -> StoriesUltraSecureBackup(isPaused, currentStep.duration())
- 4 -> StoriesCurrencies(isPaused, currentStep.duration())
- 5 -> StoriesWeb3(isPaused, currentStep.duration())
- 6 -> StoriesWalletForEveryone(currentStep.duration())
+ when (currentStory) {
+ Stories.OneInchPromo -> Learn2earnStoriesScreen(onLearn2earnClick)
+ Stories.TangemIntro -> FirstStoriesContent(isPaused, currentStory.duration) { hideContent.value = it }
+ Stories.RevolutionaryWallet -> StoriesRevolutionaryWallet(currentStory.duration)
+ Stories.UltraSecureBackup -> StoriesUltraSecureBackup(isPaused, currentStory.duration)
+ Stories.Currencies -> StoriesCurrencies(isPaused, currentStory.duration)
+ Stories.Web3 -> StoriesWeb3(isPaused, currentStory.duration)
+ Stories.WalletForEveryone -> StoriesWalletForEveryone(currentStory.duration)
}
}
Column(
@@ -186,7 +171,7 @@ fun StoriesScreen(
.align(Alignment.BottomCenter)
.fillMaxWidth(),
) {
- if (currentStep.value == 4) {
+ if (currentStory == Stories.Currencies) {
Button(
onClick = onSearchTokensClick,
modifier = Modifier
@@ -210,29 +195,31 @@ fun StoriesScreen(
)
}
}
- HomeButtons(
- modifier = Modifier
- .padding(start = 16.dp, top = 0.dp, end = 16.dp, bottom = 37.dp)
- .fillMaxWidth(),
- isDarkBackground = isDarkBackground,
- btnScanStateInProgress = homeState.value.btnScanStateInProgress,
- onScanButtonClick = onScanButtonClick,
- onShopButtonClick = onShopButtonClick,
- )
+
+ if (currentStory != Stories.OneInchPromo) {
+ HomeButtons(
+ modifier = Modifier
+ .padding(
+ start = TangemTheme.dimens.size16,
+ end = TangemTheme.dimens.size16,
+ bottom = TangemTheme.dimens.size36,
+ )
+ .fillMaxWidth(),
+ isDarkBackground = currentStory.isDarkBackground,
+ btnScanStateInProgress = homeState.value.btnScanStateInProgress,
+ onScanButtonClick = onScanButtonClick,
+ onShopButtonClick = onShopButtonClick,
+ )
+ }
}
}
}
-@Suppress("MagicNumber")
-private fun MutableState.duration(): Int = when (this.value) {
- 1 -> 8000
- else -> 6000
-}
-
@Preview
@Composable
private fun StoriesScreenPreview() {
StoriesScreen(
+ onLearn2earnClick = {},
onScanButtonClick = {},
onShopButtonClick = {},
onSearchTokensClick = {},
diff --git a/app/src/main/java/com/tangem/tap/features/home/compose/views/StoriesProgressBar.kt b/app/src/main/java/com/tangem/tap/features/home/compose/views/StoriesProgressBar.kt
index f92adcf9d1..2774f0f683 100644
--- a/app/src/main/java/com/tangem/tap/features/home/compose/views/StoriesProgressBar.kt
+++ b/app/src/main/java/com/tangem/tap/features/home/compose/views/StoriesProgressBar.kt
@@ -4,12 +4,7 @@ import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.fillMaxHeight
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.height
-import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
@@ -52,7 +47,7 @@ fun StoriesProgressBar(
// .height()
.padding(start = 9.dp, end = 9.dp, top = 16.dp),
) {
- for (index in 1..steps) {
+ for (index in 0..steps) {
Row(
modifier = Modifier
.height(2.dp)
diff --git a/app/src/main/java/com/tangem/tap/features/home/redux/HomeAction.kt b/app/src/main/java/com/tangem/tap/features/home/redux/HomeAction.kt
index bb9be2edc3..86b139defb 100644
--- a/app/src/main/java/com/tangem/tap/features/home/redux/HomeAction.kt
+++ b/app/src/main/java/com/tangem/tap/features/home/redux/HomeAction.kt
@@ -11,6 +11,8 @@ sealed class HomeAction : Action {
object OnCreate : HomeAction()
object Init : HomeAction()
+ data class InsertStory(val position: Int, val story: Stories) : HomeAction()
+
data class ReadCard(
val analyticsEvent: AnalyticsEvent? = Basic.CardWasScanned(AnalyticsParam.ScannedFrom.Introduction),
) : HomeAction()
diff --git a/app/src/main/java/com/tangem/tap/features/home/redux/HomeMiddleware.kt b/app/src/main/java/com/tangem/tap/features/home/redux/HomeMiddleware.kt
index 9d7d775e1d..7a77fcaa60 100644
--- a/app/src/main/java/com/tangem/tap/features/home/redux/HomeMiddleware.kt
+++ b/app/src/main/java/com/tangem/tap/features/home/redux/HomeMiddleware.kt
@@ -6,6 +6,8 @@ import com.tangem.common.doOnSuccess
import com.tangem.common.extensions.guard
import com.tangem.core.analytics.Analytics
import com.tangem.core.analytics.AnalyticsEvent
+import com.tangem.core.navigation.AppScreen
+import com.tangem.core.navigation.NavigationAction
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.tap.*
import com.tangem.tap.common.analytics.events.Basic
@@ -18,8 +20,6 @@ import com.tangem.tap.common.extensions.eraseContext
import com.tangem.tap.common.extensions.onUserWalletSelected
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.common.redux.global.GlobalAction
-import com.tangem.tap.common.redux.navigation.AppScreen
-import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.domain.model.builders.UserWalletBuilder
import com.tangem.tap.domain.scanCard.ScanCardProcessor
import com.tangem.tap.features.home.BELARUS_COUNTRY_CODE
diff --git a/app/src/main/java/com/tangem/tap/features/home/redux/HomeReducer.kt b/app/src/main/java/com/tangem/tap/features/home/redux/HomeReducer.kt
index f9f2911c32..6843253f5a 100644
--- a/app/src/main/java/com/tangem/tap/features/home/redux/HomeReducer.kt
+++ b/app/src/main/java/com/tangem/tap/features/home/redux/HomeReducer.kt
@@ -12,6 +12,13 @@ private fun internalReduce(action: Action, state: AppState): HomeState {
var state = state.homeState
when (action) {
+ is HomeAction.InsertStory -> {
+ state = state.copy(
+ stories = state.stories.toMutableList().apply {
+ add(action.position, action.story)
+ },
+ )
+ }
is HomeAction.ScanInProgress -> {
state = state.copy(scanInProgress = action.scanInProgress)
}
diff --git a/app/src/main/java/com/tangem/tap/features/home/redux/HomeState.kt b/app/src/main/java/com/tangem/tap/features/home/redux/HomeState.kt
index 618e432dec..415deb938d 100644
--- a/app/src/main/java/com/tangem/tap/features/home/redux/HomeState.kt
+++ b/app/src/main/java/com/tangem/tap/features/home/redux/HomeState.kt
@@ -8,8 +8,38 @@ import org.rekotlin.StateType
data class HomeState(
val scanInProgress: Boolean = false,
val btnScanState: IndeterminateProgressButton = IndeterminateProgressButton(ButtonState.ENABLED),
+ val stories: List = initDefaultStories(),
) : StateType {
+ val firstStory: Stories
+ get() = stories[0]
+
val btnScanStateInProgress: Boolean
get() = btnScanState.progressState == ProgressState.Loading
+
+ fun stepOf(story: Stories): Int = stories.indexOf(story)
+
+ companion object {
+ fun initDefaultStories(): List = listOf(
+ Stories.TangemIntro,
+ Stories.RevolutionaryWallet,
+ Stories.UltraSecureBackup,
+ Stories.Currencies,
+ Stories.Web3,
+ Stories.WalletForEveryone,
+ )
+ }
+}
+
+sealed class Stories(
+ val isDarkBackground: Boolean,
+ val duration: Int,
+) {
+ object OneInchPromo : Stories(true, duration = 8000)
+ object TangemIntro : Stories(true, duration = 8000)
+ object RevolutionaryWallet : Stories(true, duration = 6000)
+ object UltraSecureBackup : Stories(false, duration = 6000)
+ object Currencies : Stories(false, duration = 6000)
+ object Web3 : Stories(false, duration = 6000)
+ object WalletForEveryone : Stories(true, duration = 6000)
}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/features/intentHandler/IntentHandler.kt b/app/src/main/java/com/tangem/tap/features/intentHandler/IntentHandler.kt
new file mode 100644
index 0000000000..ba008d4e5a
--- /dev/null
+++ b/app/src/main/java/com/tangem/tap/features/intentHandler/IntentHandler.kt
@@ -0,0 +1,10 @@
+package com.tangem.tap.features.intentHandler
+
+import android.content.Intent
+
+/**
+[REDACTED_AUTHOR]
+ */
+interface IntentHandler {
+ suspend fun handleIntent(intent: Intent?): Boolean
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/features/intentHandler/IntentProcessor.kt b/app/src/main/java/com/tangem/tap/features/intentHandler/IntentProcessor.kt
new file mode 100644
index 0000000000..47cf6a31fd
--- /dev/null
+++ b/app/src/main/java/com/tangem/tap/features/intentHandler/IntentProcessor.kt
@@ -0,0 +1,31 @@
+package com.tangem.tap.features.intentHandler
+
+import android.content.Intent
+import java.util.concurrent.CopyOnWriteArrayList
+
+/**
+[REDACTED_AUTHOR]
+ */
+// TODO: fixme: close it with the combined interfaces IntentHandler and IntentHandlerHolder
+class IntentProcessor {
+
+ private val intentHandlers = CopyOnWriteArrayList()
+
+ fun addHandler(handler: IntentHandler) {
+ intentHandlers.add(handler)
+ }
+
+ fun removeIntentHandler(handler: IntentHandler) {
+ intentHandlers.remove(handler)
+ }
+
+ fun removeAll() {
+ intentHandlers.clear()
+ }
+
+ suspend fun handleIntent(intent: Intent?) {
+ intentHandlers.forEach {
+ it.handleIntent(intent)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/features/intentHandler/handlers/BackgroundScanIntentHandler.kt b/app/src/main/java/com/tangem/tap/features/intentHandler/handlers/BackgroundScanIntentHandler.kt
new file mode 100644
index 0000000000..18a51c222f
--- /dev/null
+++ b/app/src/main/java/com/tangem/tap/features/intentHandler/handlers/BackgroundScanIntentHandler.kt
@@ -0,0 +1,52 @@
+package com.tangem.tap.features.intentHandler.handlers
+
+import android.content.Intent
+import android.nfc.NfcAdapter
+import android.nfc.Tag
+import android.os.Build
+import com.tangem.tap.features.home.redux.HomeAction
+import com.tangem.tap.features.intentHandler.IntentHandler
+import com.tangem.tap.features.welcome.redux.WelcomeAction
+import com.tangem.tap.scope
+import com.tangem.tap.store
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+
+/**
+[REDACTED_AUTHOR]
+ */
+class BackgroundScanIntentHandler(
+ private val hasSavedUserWalletsProvider: () -> Boolean,
+) : IntentHandler {
+
+ private val nfcActions = arrayOf(
+ NfcAdapter.ACTION_NDEF_DISCOVERED,
+ NfcAdapter.ACTION_TECH_DISCOVERED,
+ NfcAdapter.ACTION_TAG_DISCOVERED,
+ )
+
+ override suspend fun handleIntent(intent: Intent?): Boolean {
+ if (intent == null || intent.action !in nfcActions) return false
+
+ val tag: Tag? = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ intent.getParcelableExtra(NfcAdapter.EXTRA_TAG, Tag::class.java)
+ } else {
+ @Suppress("DEPRECATION")
+ intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
+ }
+ if (tag == null) return false
+
+ intent.action = null
+ if (hasSavedUserWalletsProvider.invoke()) {
+ // TODO: Remove delay after [REDACTED_JIRA]
+ scope.launch {
+ delay(timeMillis = 200)
+ store.dispatch(WelcomeAction.ProceedWithCard)
+ }
+ } else {
+ store.dispatch(HomeAction.ReadCard())
+ }
+
+ return true
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/features/intentHandler/handlers/BuyCurrencyIntentHandler.kt b/app/src/main/java/com/tangem/tap/features/intentHandler/handlers/BuyCurrencyIntentHandler.kt
new file mode 100644
index 0000000000..39dda7cd24
--- /dev/null
+++ b/app/src/main/java/com/tangem/tap/features/intentHandler/handlers/BuyCurrencyIntentHandler.kt
@@ -0,0 +1,30 @@
+package com.tangem.tap.features.intentHandler.handlers
+
+import android.content.Intent
+import android.net.Uri
+import com.tangem.core.analytics.Analytics
+import com.tangem.tap.common.analytics.events.AnalyticsParam
+import com.tangem.tap.common.analytics.events.Token
+import com.tangem.tap.features.intentHandler.IntentHandler
+import com.tangem.tap.network.exchangeServices.ExchangeUrlBuilder
+import com.tangem.tap.store
+
+/**
+[REDACTED_AUTHOR]
+ */
+class BuyCurrencyIntentHandler : IntentHandler {
+
+ override suspend fun handleIntent(intent: Intent?): Boolean {
+ val data = intent?.data ?: return false
+ val currency = store.state.walletState.selectedCurrency ?: return false
+
+ val successUri = Uri.parse(ExchangeUrlBuilder.SUCCESS_URL)
+ return if (data.host == successUri.host && data.authority == successUri.authority) {
+ val currencyType = AnalyticsParam.CurrencyType.Currency(currency)
+ Analytics.send(Token.Bought(currencyType))
+ true
+ } else {
+ false
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/features/intentHandler/handlers/SellCurrencyIntentHandler.kt b/app/src/main/java/com/tangem/tap/features/intentHandler/handlers/SellCurrencyIntentHandler.kt
new file mode 100644
index 0000000000..3fc6c318d6
--- /dev/null
+++ b/app/src/main/java/com/tangem/tap/features/intentHandler/handlers/SellCurrencyIntentHandler.kt
@@ -0,0 +1,44 @@
+package com.tangem.tap.features.intentHandler.handlers
+
+import android.content.Intent
+import com.tangem.tap.features.intentHandler.IntentHandler
+import com.tangem.tap.features.wallet.redux.WalletAction
+import com.tangem.tap.store
+import timber.log.Timber
+
+/**
+[REDACTED_AUTHOR]
+ */
+class SellCurrencyIntentHandler : IntentHandler {
+
+ override suspend fun handleIntent(intent: Intent?): Boolean {
+ return try {
+ val intentData = intent?.data ?: return false
+ val transactionID = intentData.getQueryParameter(TRANSACTION_ID_PARAM) ?: return false
+ val currency = intentData.getQueryParameter(CURRENCY_CODE_PARAM) ?: return false
+ val amount = intentData.getQueryParameter(CURRENCY_AMOUNT_PARAM) ?: return false
+ val destinationAddress = intentData.getQueryParameter(DEPOSIT_WALLET_ADDRESS_PARAM) ?: return false
+
+ Timber.d("MoonPay Sell: $amount $currency to $destinationAddress")
+ store.dispatch(
+ WalletAction.TradeCryptoAction.SendCrypto(
+ currencyId = currency,
+ amount = amount,
+ destinationAddress = destinationAddress,
+ transactionId = transactionID,
+ ),
+ )
+ true
+ } catch (exception: Exception) {
+ Timber.d("Not MoonPay URL")
+ false
+ }
+ }
+
+ private companion object {
+ private const val TRANSACTION_ID_PARAM = "transactionId"
+ private const val CURRENCY_CODE_PARAM = "baseCurrencyCode"
+ private const val CURRENCY_AMOUNT_PARAM = "baseCurrencyAmount"
+ private const val DEPOSIT_WALLET_ADDRESS_PARAM = "depositWalletAddress"
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/features/intentHandler/handlers/WalletConnectLinkIntentHandler.kt b/app/src/main/java/com/tangem/tap/features/intentHandler/handlers/WalletConnectLinkIntentHandler.kt
new file mode 100644
index 0000000000..e61d0b74d7
--- /dev/null
+++ b/app/src/main/java/com/tangem/tap/features/intentHandler/handlers/WalletConnectLinkIntentHandler.kt
@@ -0,0 +1,37 @@
+package com.tangem.tap.features.intentHandler.handlers
+
+import android.content.Intent
+import com.tangem.tap.common.extensions.removePrefixOrNull
+import com.tangem.tap.domain.walletconnect.WalletConnectManager
+import com.tangem.tap.features.details.redux.walletconnect.WalletConnectAction
+import com.tangem.tap.features.intentHandler.IntentHandler
+import com.tangem.tap.store
+
+/**
+[REDACTED_AUTHOR]
+ */
+class WalletConnectLinkIntentHandler : IntentHandler {
+
+ override suspend fun handleIntent(intent: Intent?): Boolean {
+ val intentData = intent?.data ?: return false
+ val scheme = intent.scheme ?: return false
+
+ val wcUri = when (scheme) {
+ WalletConnectManager.WC_SCHEME -> intentData.toString()
+ TANGEM_SCHEME -> intentData.toString().removePrefixOrNull(TANGEM_WC_PREFIX)
+ else -> null
+ }
+
+ return if (wcUri == null) {
+ false
+ } else {
+ store.dispatch(WalletConnectAction.HandleDeepLink(wcUri))
+ true
+ }
+ }
+
+ private companion object {
+ private const val TANGEM_SCHEME = "tangem"
+ private const val TANGEM_WC_PREFIX = "tangem://wc?uri="
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingHelper.kt b/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingHelper.kt
index 6079110e39..477ab679c6 100644
--- a/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingHelper.kt
+++ b/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingHelper.kt
@@ -4,23 +4,19 @@ import com.tangem.common.doOnFailure
import com.tangem.common.doOnSuccess
import com.tangem.common.extensions.guard
import com.tangem.core.analytics.Analytics
+import com.tangem.core.navigation.AppScreen
+import com.tangem.core.navigation.NavigationAction
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.domain.common.util.twinsIsTwinned
import com.tangem.domain.models.scan.ProductType
import com.tangem.domain.models.scan.ScanResponse
+import com.tangem.tap.*
import com.tangem.tap.common.extensions.dispatchOnMain
import com.tangem.tap.common.extensions.onUserWalletSelected
import com.tangem.tap.common.extensions.removeContext
import com.tangem.tap.common.extensions.setContext
-import com.tangem.tap.common.redux.navigation.AppScreen
-import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.domain.model.builders.UserWalletBuilder
import com.tangem.tap.features.saveWallet.redux.SaveWalletAction
-import com.tangem.tap.preferencesStorage
-import com.tangem.tap.scope
-import com.tangem.tap.store
-import com.tangem.tap.tangemSdkManager
-import com.tangem.tap.userWalletsListManager
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import timber.log.Timber
diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/note/OnboardingNoteFragment.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/note/OnboardingNoteFragment.kt
index 39fea7dbfd..cf68e35486 100644
--- a/app/src/main/java/com/tangem/tap/features/onboarding/products/note/OnboardingNoteFragment.kt
+++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/note/OnboardingNoteFragment.kt
@@ -10,10 +10,10 @@ import androidx.transition.TransitionManager
import coil.load
import com.tangem.blockchain.common.Blockchain
import com.tangem.core.analytics.Analytics
+import com.tangem.core.navigation.ShareElement
import com.tangem.tap.common.analytics.events.Onboarding
import com.tangem.tap.common.extensions.getDrawableCompat
import com.tangem.tap.common.extensions.stripZeroPlainString
-import com.tangem.tap.common.redux.navigation.ShareElement
import com.tangem.tap.common.toggleWidget.RefreshBalanceWidget
import com.tangem.tap.common.transitions.InternalNoteLayoutTransition
import com.tangem.tap.features.addBackPressHandler
diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/note/redux/OnboardingNoteMiddleware.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/note/redux/OnboardingNoteMiddleware.kt
index fddc46b3a8..0006840098 100644
--- a/app/src/main/java/com/tangem/tap/features/onboarding/products/note/redux/OnboardingNoteMiddleware.kt
+++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/note/redux/OnboardingNoteMiddleware.kt
@@ -3,22 +3,16 @@ package com.tangem.tap.features.onboarding.products.note.redux
import com.tangem.common.CompletionResult
import com.tangem.common.extensions.guard
import com.tangem.core.analytics.Analytics
+import com.tangem.core.navigation.NavigationAction
import com.tangem.domain.common.extensions.withMainContext
import com.tangem.tap.DELAY_SDK_DIALOG_CLOSE
import com.tangem.tap.common.analytics.events.AnalyticsParam
import com.tangem.tap.common.analytics.events.Onboarding
-import com.tangem.tap.common.extensions.dispatchDebugErrorNotification
-import com.tangem.tap.common.extensions.dispatchDialogShow
-import com.tangem.tap.common.extensions.dispatchErrorNotification
-import com.tangem.tap.common.extensions.dispatchOnMain
-import com.tangem.tap.common.extensions.dispatchOpenUrl
-import com.tangem.tap.common.extensions.getAddressData
-import com.tangem.tap.common.extensions.getTopUpUrl
+import com.tangem.tap.common.extensions.*
import com.tangem.tap.common.postUi
import com.tangem.tap.common.redux.AppDialog
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.common.redux.global.GlobalAction
-import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.domain.TapError
import com.tangem.tap.domain.extensions.makePrimaryWalletManager
import com.tangem.tap.features.demo.DemoHelper
diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/OnboardingOtherCardsFragment.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/OnboardingOtherCardsFragment.kt
index 5080265552..83674d9227 100644
--- a/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/OnboardingOtherCardsFragment.kt
+++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/OnboardingOtherCardsFragment.kt
@@ -9,9 +9,9 @@ import androidx.core.view.isVisible
import androidx.transition.TransitionManager
import coil.load
import com.tangem.core.analytics.Analytics
+import com.tangem.core.navigation.ShareElement
import com.tangem.tap.common.analytics.events.Onboarding
import com.tangem.tap.common.extensions.getDrawableCompat
-import com.tangem.tap.common.redux.navigation.ShareElement
import com.tangem.tap.common.transitions.InternalNoteLayoutTransition
import com.tangem.tap.features.addBackPressHandler
import com.tangem.tap.features.onboarding.products.BaseOnboardingFragment
diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/redux/OnboardingOtherCardsMiddleware.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/redux/OnboardingOtherCardsMiddleware.kt
index ba7983eaa5..00a9d94af5 100644
--- a/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/redux/OnboardingOtherCardsMiddleware.kt
+++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/redux/OnboardingOtherCardsMiddleware.kt
@@ -3,20 +3,16 @@ package com.tangem.tap.features.onboarding.products.otherCards.redux
import com.tangem.blockchain.common.Blockchain
import com.tangem.common.CompletionResult
import com.tangem.core.analytics.Analytics
-import com.tangem.domain.common.util.cardTypesResolver
+import com.tangem.domain.common.BlockchainNetwork
import com.tangem.domain.common.extensions.withMainContext
-import com.tangem.tap.DELAY_SDK_DIALOG_CLOSE
+import com.tangem.domain.common.util.cardTypesResolver
+import com.tangem.tap.*
import com.tangem.tap.common.analytics.events.Onboarding
import com.tangem.tap.common.postUi
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.common.redux.global.GlobalAction
-import com.tangem.tap.domain.tokens.models.BlockchainNetwork
import com.tangem.tap.features.onboarding.OnboardingHelper
import com.tangem.tap.features.wallet.models.toCurrencies
-import com.tangem.tap.scope
-import com.tangem.tap.store
-import com.tangem.tap.tangemSdkManager
-import com.tangem.tap.userTokensRepository
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.rekotlin.Action
diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsMiddleware.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsMiddleware.kt
index 036482c623..af0338bb49 100644
--- a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsMiddleware.kt
+++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsMiddleware.kt
@@ -4,6 +4,8 @@ import com.tangem.blockchain.extensions.Result
import com.tangem.common.CompletionResult
import com.tangem.common.extensions.guard
import com.tangem.core.analytics.Analytics
+import com.tangem.core.navigation.AppScreen
+import com.tangem.core.navigation.NavigationAction
import com.tangem.domain.common.extensions.withMainContext
import com.tangem.domain.common.util.twinsIsTwinned
import com.tangem.domain.models.scan.ScanResponse
@@ -15,8 +17,6 @@ import com.tangem.tap.common.postUi
import com.tangem.tap.common.redux.AppDialog
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.common.redux.global.GlobalAction
-import com.tangem.tap.common.redux.navigation.AppScreen
-import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.domain.TapError
import com.tangem.tap.domain.extensions.makePrimaryWalletManager
import com.tangem.tap.domain.model.builders.UserWalletIdBuilder
diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/ui/TwinsCardsFragment.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/ui/TwinsCardsFragment.kt
index 1ef2872944..77bc7f7310 100644
--- a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/ui/TwinsCardsFragment.kt
+++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/ui/TwinsCardsFragment.kt
@@ -14,6 +14,7 @@ import com.tangem.Message
import com.tangem.blockchain.common.Blockchain
import com.tangem.common.extensions.VoidCallback
import com.tangem.core.analytics.Analytics
+import com.tangem.core.navigation.ShareElement
import com.tangem.core.ui.fragments.setStatusBarColor
import com.tangem.datasource.asset.AssetReader
import com.tangem.domain.models.scan.ScanResponse
@@ -25,7 +26,6 @@ import com.tangem.tap.common.extensions.getDrawableCompat
import com.tangem.tap.common.extensions.hide
import com.tangem.tap.common.extensions.show
import com.tangem.tap.common.extensions.stripZeroPlainString
-import com.tangem.tap.common.redux.navigation.ShareElement
import com.tangem.tap.common.toggleWidget.RefreshBalanceWidget
import com.tangem.tap.common.transitions.InternalNoteLayoutTransition
import com.tangem.tap.domain.twins.TwinsCardWidget
diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletMiddleware.kt
index 2f4be5416d..67921cce64 100644
--- a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletMiddleware.kt
+++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletMiddleware.kt
@@ -6,6 +6,9 @@ import com.tangem.common.CompletionResult
import com.tangem.common.core.TangemSdkError
import com.tangem.common.extensions.ifNotNull
import com.tangem.core.analytics.Analytics
+import com.tangem.core.navigation.AppScreen
+import com.tangem.core.navigation.NavigationAction
+import com.tangem.domain.common.BlockchainNetwork
import com.tangem.domain.common.extensions.withMainContext
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.domain.models.scan.CardDTO
@@ -20,10 +23,7 @@ import com.tangem.tap.common.extensions.dispatchDialogShow
import com.tangem.tap.common.extensions.dispatchOnMain
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.common.redux.global.GlobalAction
-import com.tangem.tap.common.redux.navigation.AppScreen
-import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.domain.tasks.product.CreateProductWalletTaskResponse
-import com.tangem.tap.domain.tokens.models.BlockchainNetwork
import com.tangem.tap.features.demo.DemoHelper
import com.tangem.tap.features.home.redux.HomeAction
import com.tangem.tap.features.onboarding.OnboardingDialog
diff --git a/app/src/main/java/com/tangem/tap/features/saveWallet/redux/SaveWalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/saveWallet/redux/SaveWalletMiddleware.kt
index ec2223b2bd..945fc90afd 100644
--- a/app/src/main/java/com/tangem/tap/features/saveWallet/redux/SaveWalletMiddleware.kt
+++ b/app/src/main/java/com/tangem/tap/features/saveWallet/redux/SaveWalletMiddleware.kt
@@ -7,6 +7,10 @@ import com.tangem.common.doOnSuccess
import com.tangem.common.extensions.guard
import com.tangem.common.flatMap
import com.tangem.core.analytics.Analytics
+import com.tangem.core.navigation.AppScreen
+import com.tangem.core.navigation.NavigationAction
+import com.tangem.domain.wallets.legacy.UserWalletsListManager
+import com.tangem.tap.*
import com.tangem.tap.common.analytics.events.AnalyticsParam
import com.tangem.tap.common.analytics.events.MainScreen
import com.tangem.tap.common.analytics.events.Onboarding
@@ -14,19 +18,10 @@ import com.tangem.tap.common.extensions.dispatchOnMain
import com.tangem.tap.common.extensions.dispatchWithMain
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.common.redux.global.GlobalAction
-import com.tangem.tap.common.redux.navigation.AppScreen
-import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.domain.model.builders.UserWalletBuilder
-import com.tangem.tap.domain.userWalletList.UserWalletsListManager
import com.tangem.tap.domain.userWalletList.di.provideBiometricImplementation
import com.tangem.tap.domain.userWalletList.isLockable
import com.tangem.tap.features.wallet.redux.WalletAction
-import com.tangem.tap.foregroundActivityObserver
-import com.tangem.tap.preferencesStorage
-import com.tangem.tap.scope
-import com.tangem.tap.store
-import com.tangem.tap.tangemSdkManager
-import com.tangem.tap.userWalletsListManager
import kotlinx.coroutines.launch
import org.rekotlin.Middleware
import timber.log.Timber
diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt b/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt
index 20c206b37d..5f92c3c10b 100644
--- a/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt
+++ b/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt
@@ -6,7 +6,6 @@ import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.WalletManager
import com.tangem.common.core.TangemSdkError
import com.tangem.tap.common.analytics.events.Token.Send.AddressEntered
-import com.tangem.tap.common.redux.ErrorAction
import com.tangem.tap.common.redux.StateDialog
import com.tangem.tap.common.redux.ToastNotificationAction
import com.tangem.tap.domain.TapError
@@ -34,15 +33,14 @@ data class PrepareSendScreen(
val tokenRate: BigDecimal? = null,
) : SendScreenAction
-// Address or PayId
-sealed class AddressPayIdActionUi : SendScreenActionUi {
- data class HandleUserInput(val data: String) : AddressPayIdActionUi()
- data class PasteAddressPayId(val data: String, val sourceType: AddressEntered.SourceType) : AddressPayIdActionUi()
- data class CheckClipboard(val data: String?) : AddressPayIdActionUi()
- data class CheckAddressPayId(val sourceType: AddressEntered.SourceType?) : AddressPayIdActionUi()
- data class SetTruncateHandler(val handler: (String) -> String) : AddressPayIdActionUi()
- data class TruncateOrRestore(val truncate: Boolean) : AddressPayIdActionUi()
- data class ChangePayIdState(val sendingToPayIdEnabled: Boolean) : AddressPayIdActionUi()
+// Address
+sealed class AddressActionUi : SendScreenActionUi {
+ data class HandleUserInput(val data: String) : AddressActionUi()
+ data class PasteAddress(val data: String, val sourceType: AddressEntered.SourceType) : AddressActionUi()
+ data class CheckClipboard(val data: String?) : AddressActionUi()
+ data class CheckAddress(val sourceType: AddressEntered.SourceType?) : AddressActionUi()
+ data class SetTruncateHandler(val handler: (String) -> String) : AddressActionUi()
+ data class TruncateOrRestore(val truncate: Boolean) : AddressActionUi()
}
sealed class TransactionExtrasAction : SendScreenActionUi {
@@ -76,27 +74,15 @@ sealed class TransactionExtrasAction : SendScreenActionUi {
}
}
-sealed class AddressPayIdVerifyAction : SendScreenAction {
+sealed class AddressVerifyAction : SendScreenAction {
enum class Error {
- PAY_ID_UNSUPPORTED_BY_BLOCKCHAIN,
- PAY_ID_NOT_REGISTERED,
- PAY_ID_REQUEST_FAILED,
ADDRESS_INVALID_OR_UNSUPPORTED_BY_BLOCKCHAIN,
ADDRESS_SAME_AS_WALLET,
}
- data class ChangePasteBtnEnableState(val isEnabled: Boolean) : AddressPayIdVerifyAction()
+ data class ChangePasteBtnEnableState(val isEnabled: Boolean) : AddressVerifyAction()
- sealed class PayIdVerification : AddressPayIdVerifyAction() {
- data class SetPayIdError(val error: Error?) : PayIdVerification()
- data class SetPayIdWalletAddress(
- val payId: String,
- val payIdWalletAddress: String,
- val isUserInput: Boolean,
- ) : PayIdVerification()
- }
-
- sealed class AddressVerification : AddressPayIdVerifyAction() {
+ sealed class AddressVerification : AddressVerifyAction() {
data class SetAddressError(val error: Error?) : AddressVerification()
data class SetWalletAddress(val address: String, val isUserInput: Boolean) : AddressVerification()
}
@@ -155,8 +141,6 @@ sealed class SendAction : SendScreenAction {
override val messageResource: Int = R.string.send_transaction_success
}
- data class SendError(override val error: TapError) : SendAction(), ErrorAction
-
sealed class Dialog : SendAction(), StateDialog {
data class TezosWarningDialog(
val reduceCallback: () -> Unit,
diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AddressPayIdMiddleware.kt b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AddressMiddleware.kt
similarity index 50%
rename from app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AddressPayIdMiddleware.kt
rename to app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AddressMiddleware.kt
index 406eacd087..576497222e 100644
--- a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AddressPayIdMiddleware.kt
+++ b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AddressMiddleware.kt
@@ -2,49 +2,39 @@ package com.tangem.tap.features.send.redux.middlewares
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.Wallet
-import com.tangem.common.services.Result
import com.tangem.core.analytics.Analytics
import com.tangem.tap.common.analytics.events.Token.Send.AddressEntered
import com.tangem.tap.common.redux.AppState
-import com.tangem.tap.domain.PayIdManager
-import com.tangem.tap.domain.isPayIdSupported
import com.tangem.tap.features.send.redux.*
-import com.tangem.tap.features.send.redux.AddressPayIdVerifyAction.AddressVerification.SetAddressError
-import com.tangem.tap.features.send.redux.AddressPayIdVerifyAction.AddressVerification.SetWalletAddress
-import com.tangem.tap.features.send.redux.AddressPayIdVerifyAction.Error
-import com.tangem.tap.features.send.redux.AddressPayIdVerifyAction.PayIdVerification.SetPayIdError
-import com.tangem.tap.features.send.redux.AddressPayIdVerifyAction.PayIdVerification.SetPayIdWalletAddress
-import com.tangem.tap.scope
-import com.tangem.tap.store
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.withContext
+import com.tangem.tap.features.send.redux.AddressVerifyAction.AddressVerification.SetAddressError
+import com.tangem.tap.features.send.redux.AddressVerifyAction.AddressVerification.SetWalletAddress
+import com.tangem.tap.features.send.redux.AddressVerifyAction.Error
import org.rekotlin.Action
import org.rekotlin.DispatchFunction
/**
[REDACTED_AUTHOR]
*/
-internal class AddressPayIdMiddleware {
+internal class AddressMiddleware {
- fun handle(action: AddressPayIdActionUi, appState: AppState?, dispatch: (Action) -> Unit) {
+ fun handle(action: AddressActionUi, appState: AppState?, dispatch: (Action) -> Unit) {
when (action) {
- is AddressPayIdActionUi.HandleUserInput -> handleUserInput(action.data, appState, dispatch)
- is AddressPayIdActionUi.PasteAddressPayId -> pasteAddressPayId(action.data, action.sourceType, dispatch)
- is AddressPayIdActionUi.CheckClipboard -> verifyClipboard(action.data, appState, dispatch)
- is AddressPayIdActionUi.CheckAddressPayId -> verifyAddressPayId(action.sourceType, appState, dispatch)
+ is AddressActionUi.HandleUserInput -> handleUserInput(action.data, appState, dispatch)
+ is AddressActionUi.PasteAddress -> pasteAddress(action.data, action.sourceType, dispatch)
+ is AddressActionUi.CheckClipboard -> verifyClipboard(action.data, appState, dispatch)
+ is AddressActionUi.CheckAddress -> verifyAddress(action.sourceType, appState, dispatch)
else -> return
}
}
private fun handleUserInput(input: String, appState: AppState?, dispatch: DispatchFunction) {
val sendState = appState?.sendState ?: return
- if (input == sendState.addressPayIdState.viewFieldValue.value) return
+ if (input == sendState.addressState.viewFieldValue.value) return
setAddressAndCheck(data = input, sourceType = null, isUserInput = true, dispatch = dispatch)
}
- private fun pasteAddressPayId(data: String, sourceType: AddressEntered.SourceType, dispatch: (Action) -> Unit) {
+ private fun pasteAddress(data: String, sourceType: AddressEntered.SourceType, dispatch: (Action) -> Unit) {
setAddressAndCheck(data = data, sourceType = sourceType, isUserInput = false, dispatch = dispatch)
}
@@ -54,74 +44,27 @@ internal class AddressPayIdMiddleware {
isUserInput: Boolean,
dispatch: (Action) -> Unit,
) {
- val potentialPayId = data.lowercase()
- if (isPayIdEnabled() && PayIdManager.isPayId(potentialPayId)) {
- dispatch(SetPayIdWalletAddress(potentialPayId, "", isUserInput))
- } else {
- dispatch(SetWalletAddress(data, isUserInput))
- }
- dispatch(AddressPayIdActionUi.CheckAddressPayId(sourceType))
+ dispatch(SetWalletAddress(data, isUserInput))
+ dispatch(AddressActionUi.CheckAddress(sourceType))
}
- private fun verifyAddressPayId(
+ private fun verifyAddress(
sourceType: AddressEntered.SourceType?,
appState: AppState?,
dispatch: (Action) -> Unit,
) {
val sendState = appState?.sendState ?: return
val wallet = sendState.walletManager?.wallet ?: return
- val addressPayId = sendState.addressPayIdState.normalFieldValue ?: return
- val isUserInput = sendState.addressPayIdState.viewFieldValue.isFromUserInput
+ val address = sendState.addressState.normalFieldValue ?: return
+ val isUserInput = sendState.addressState.viewFieldValue.isFromUserInput
- if (isPayIdEnabled() && PayIdManager.isPayId(addressPayId)) {
- verifyPayId(addressPayId, wallet, isUserInput, dispatch)
- } else {
- verifyAddress(
- address = addressPayId,
- wallet = wallet,
- isUserInput = isUserInput,
- dispatch = dispatch,
- sourceType = sourceType,
- )
- }
- }
-
- private fun verifyPayId(payId: String, wallet: Wallet, isUserInput: Boolean, dispatch: DispatchFunction) {
- val blockchain = wallet.blockchain
- if (!blockchain.isPayIdSupported()) {
- dispatch(SetPayIdError(Error.PAY_ID_UNSUPPORTED_BY_BLOCKCHAIN))
- return
- }
-
- scope.launch {
- val result = PayIdManager().verifyPayId(payId, blockchain)
- withContext(Dispatchers.Main) {
- when (result) {
- is Result.Success -> {
- val addressDetails = result.data.getAddressDetails()
- if (addressDetails == null) {
- dispatch(SetPayIdError(Error.PAY_ID_NOT_REGISTERED))
- return@withContext
- }
-
- val address = addressDetails.address
- val failReason = isValidBlockchainAddressAndNotTheSameAsWallet(wallet, address)
- if (failReason == null) {
- dispatch(SetPayIdWalletAddress(payId, address, isUserInput))
- dispatch(TransactionExtrasAction.Prepare(wallet.blockchain, address, addressDetails.tag))
- dispatch(FeeAction.RequestFee)
- } else {
- dispatch(SetAddressError(failReason))
- dispatch(TransactionExtrasAction.Release)
- }
- }
- is Result.Failure -> {
- dispatch(SetPayIdError(Error.PAY_ID_REQUEST_FAILED))
- dispatch(TransactionExtrasAction.Release)
- }
- }
- }
- }
+ verifyAddress(
+ address = address,
+ wallet = wallet,
+ isUserInput = isUserInput,
+ dispatch = dispatch,
+ sourceType = sourceType,
+ )
}
private fun verifyAddress(
@@ -219,41 +162,33 @@ internal class AddressPayIdMiddleware {
}
private fun verifyClipboard(input: String?, appState: AppState?, dispatch: DispatchFunction) {
- val addressPayId = input ?: return
+ val address = input ?: return
val wallet = appState?.sendState?.walletManager?.wallet ?: return
val internalDispatcher: (Action) -> Unit = {
when (it) {
- is SetWalletAddress, is SetPayIdWalletAddress -> {
- dispatch(AddressPayIdVerifyAction.ChangePasteBtnEnableState(true))
+ is SetWalletAddress -> {
+ dispatch(AddressVerifyAction.ChangePasteBtnEnableState(true))
}
- is SetAddressError, is SetPayIdError -> {
- dispatch(AddressPayIdVerifyAction.ChangePasteBtnEnableState(false))
+ is SetAddressError -> {
+ dispatch(AddressVerifyAction.ChangePasteBtnEnableState(false))
}
}
}
- if (PayIdManager.isPayId(addressPayId) && isPayIdEnabled()) {
- verifyPayId(addressPayId, wallet, false, internalDispatcher)
- } else {
- verifyAddress(
- address = addressPayId,
- wallet = wallet,
- sourceType = null,
- isUserInput = false,
- dispatch = internalDispatcher,
- )
- }
- }
-
- private fun isPayIdEnabled(): Boolean {
- return store.state.globalState.configManager?.config?.isSendingToPayIdEnabled ?: false
+ verifyAddress(
+ address = address,
+ wallet = wallet,
+ sourceType = null,
+ isUserInput = false,
+ dispatch = internalDispatcher,
+ )
}
}
fun String.splitToMap(firstDelimiter: String, secondDelimiter: String): Map {
- return this.split(firstDelimiter)
+ return this
+ .split(firstDelimiter)
.map { it.split(secondDelimiter) }
- .map { it.first() to it.last().toString() }
- .toMap()
+ .associate { it.first() to it.last() }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/RequestFeeMiddleware.kt b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/RequestFeeMiddleware.kt
index 8a0b096c4c..3cbd54e044 100644
--- a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/RequestFeeMiddleware.kt
+++ b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/RequestFeeMiddleware.kt
@@ -38,7 +38,7 @@ class RequestFeeMiddleware {
}
val typedAmount = sendState.amountState.amountToExtract ?: return
- val destinationAddress = sendState.addressPayIdState.destinationWalletAddress!!
+ val destinationAddress = sendState.addressState.destinationWalletAddress!!
val destinationAmount = Amount(typedAmount, sendState.amountState.amountToSendCrypto)
val txSender = if (scanResponse.isDemoCard()) {
DemoTransactionSender(walletManager)
diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt
index d54adda3d5..af8480549a 100644
--- a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt
+++ b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt
@@ -7,6 +7,7 @@ import com.tangem.blockchain.blockchains.polkadot.ExistentialDepositProvider
import com.tangem.blockchain.blockchains.stellar.StellarTransactionExtras
import com.tangem.blockchain.blockchains.ton.TonTransactionExtras
import com.tangem.blockchain.blockchains.xrp.XrpTransactionBuilder.XrpTransactionExtras
+import com.tangem.core.navigation.NavigationAction
import com.tangem.blockchain.common.*
import com.tangem.blockchain.extensions.SimpleResult
import com.tangem.common.core.TangemSdkError
@@ -26,7 +27,6 @@ import com.tangem.tap.common.extensions.*
import com.tangem.tap.common.redux.AppDialog
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.common.redux.global.GlobalAction
-import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.domain.TangemSigner
import com.tangem.tap.domain.TapError
import com.tangem.tap.domain.configurable.warningMessage.WarningMessage
@@ -55,18 +55,17 @@ class SendMiddleware {
{ nextDispatch ->
{ action ->
when (action) {
- is AddressPayIdActionUi -> AddressPayIdMiddleware().handle(action, appState(), dispatch)
+ is AddressActionUi -> AddressMiddleware().handle(action, appState(), dispatch)
is AmountActionUi -> AmountMiddleware().handle(action, appState(), dispatch)
is RequestFee -> RequestFeeMiddleware().handle(appState(), dispatch)
is SendActionUi.SendAmountToRecipient ->
verifyAndSendTransaction(action, appState(), dispatch)
- is PrepareSendScreen -> setIfSendingToPayIdEnabled(appState(), dispatch)
is SendAction.Warnings.Update -> updateWarnings(dispatch)
is SendActionUi.CheckIfTransactionDataWasProvided -> {
val transactionData = appState()?.sendState?.externalTransactionData
if (transactionData != null) {
store.dispatchOnMain(
- AddressPayIdVerifyAction.AddressVerification.SetWalletAddress(
+ AddressVerifyAction.AddressVerification.SetWalletAddress(
address = transactionData.destinationAddress,
isUserInput = false,
),
@@ -96,7 +95,7 @@ private fun verifyAndSendTransaction(
val sendState = appState?.sendState ?: return
val walletManager = sendState.walletManager ?: return
val card = appState.globalState.scanResponse?.card ?: return
- val destinationAddress = sendState.addressPayIdState.destinationWalletAddress ?: return
+ val destinationAddress = sendState.addressState.destinationWalletAddress ?: return
val typedAmount = sendState.amountState.amountToExtract ?: return
val feeAmount = sendState.feeState.currentFee ?: return
@@ -391,12 +390,6 @@ fun createValidateTransactionError(
return TapError.ValidateTransactionErrors(tapErrors) { it.joinToString("\r\n") }
}
-private fun setIfSendingToPayIdEnabled(appState: AppState?, dispatch: (Action) -> Unit) {
- val isSendingToPayIdEnabled =
- appState?.globalState?.configManager?.config?.isSendingToPayIdEnabled ?: false
- dispatch(AddressPayIdActionUi.ChangePayIdState(isSendingToPayIdEnabled))
-}
-
private fun updateWarnings(dispatch: (Action) -> Unit) {
val warningsManager = store.state.globalState.warningManager ?: return
val blockchain = store.state.sendState.walletManager?.wallet?.blockchain ?: return
diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/AddressPayIdReducer.kt b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/AddressPayIdReducer.kt
deleted file mode 100644
index ddacac0df8..0000000000
--- a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/AddressPayIdReducer.kt
+++ /dev/null
@@ -1,72 +0,0 @@
-package com.tangem.tap.features.send.redux.reducers
-
-import com.tangem.tap.features.send.redux.AddressPayIdActionUi
-import com.tangem.tap.features.send.redux.AddressPayIdVerifyAction
-import com.tangem.tap.features.send.redux.AddressPayIdVerifyAction.AddressVerification
-import com.tangem.tap.features.send.redux.AddressPayIdVerifyAction.PayIdVerification
-import com.tangem.tap.features.send.redux.SendScreenAction
-import com.tangem.tap.features.send.redux.states.AddressPayIdState
-import com.tangem.tap.features.send.redux.states.InputViewValue
-import com.tangem.tap.features.send.redux.states.SendState
-
-/**
-[REDACTED_AUTHOR]
- */
-class AddressPayIdReducer : SendInternalReducer {
- override fun handle(action: SendScreenAction, sendState: SendState): SendState = when (action) {
- is AddressPayIdActionUi -> handleUiAction(action, sendState, sendState.addressPayIdState)
- is AddressPayIdVerifyAction -> handleAction(action, sendState, sendState.addressPayIdState)
- else -> sendState
- }
-
- private fun handleUiAction(
- action: AddressPayIdActionUi,
- sendState: SendState,
- state: AddressPayIdState,
- ): SendState {
- val result = when (action) {
- is AddressPayIdActionUi.HandleUserInput -> state
- is AddressPayIdActionUi.SetTruncateHandler -> state.copy(truncateHandler = action.handler)
- is AddressPayIdActionUi.TruncateOrRestore -> {
- val value = if (action.truncate) state.truncatedFieldValue ?: "" else state.normalFieldValue ?: ""
- state.copy(viewFieldValue = state.viewFieldValue.copy(value = value))
- }
- is AddressPayIdActionUi.PasteAddressPayId -> return sendState
- is AddressPayIdActionUi.CheckClipboard -> return sendState
- is AddressPayIdActionUi.CheckAddressPayId -> return sendState
- is AddressPayIdActionUi.ChangePayIdState -> state.copy(sendingToPayIdEnabled = action.sendingToPayIdEnabled)
- }
- return updateLastState(sendState.copy(addressPayIdState = result), result)
- }
-
- private fun handleAction(
- action: AddressPayIdVerifyAction,
- sendState: SendState,
- state: AddressPayIdState,
- ): SendState {
- val result = when (action) {
- is PayIdVerification.SetPayIdWalletAddress -> {
- state.copy(
- viewFieldValue = InputViewValue(action.payId, action.isUserInput),
- normalFieldValue = action.payId,
- truncatedFieldValue = state.truncate(action.payId),
- destinationWalletAddress = action.payIdWalletAddress,
- error = null,
- )
- }
- is AddressVerification.SetWalletAddress -> {
- state.copy(
- viewFieldValue = InputViewValue(action.address, action.isUserInput),
- normalFieldValue = action.address,
- truncatedFieldValue = state.truncate(action.address),
- destinationWalletAddress = action.address,
- error = null,
- )
- }
- is AddressPayIdVerifyAction.ChangePasteBtnEnableState -> state.copy(pasteIsEnabled = action.isEnabled)
- is AddressVerification.SetAddressError -> state.copy(error = action.error, destinationWalletAddress = null)
- is PayIdVerification.SetPayIdError -> state.copy(error = action.error, destinationWalletAddress = null)
- }
- return updateLastState(sendState.copy(addressPayIdState = result), result)
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/AddressReducer.kt b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/AddressReducer.kt
new file mode 100644
index 0000000000..a5b44bff0f
--- /dev/null
+++ b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/AddressReducer.kt
@@ -0,0 +1,52 @@
+package com.tangem.tap.features.send.redux.reducers
+
+import com.tangem.tap.features.send.redux.AddressActionUi
+import com.tangem.tap.features.send.redux.AddressVerifyAction
+import com.tangem.tap.features.send.redux.AddressVerifyAction.AddressVerification
+import com.tangem.tap.features.send.redux.SendScreenAction
+import com.tangem.tap.features.send.redux.states.AddressState
+import com.tangem.tap.features.send.redux.states.InputViewValue
+import com.tangem.tap.features.send.redux.states.SendState
+
+/**
+[REDACTED_AUTHOR]
+ */
+class AddressReducer : SendInternalReducer {
+ override fun handle(action: SendScreenAction, sendState: SendState): SendState = when (action) {
+ is AddressActionUi -> handleUiAction(action, sendState, sendState.addressState)
+ is AddressVerifyAction -> handleAction(action, sendState, sendState.addressState)
+ else -> sendState
+ }
+
+ private fun handleUiAction(action: AddressActionUi, sendState: SendState, state: AddressState): SendState {
+ val result = when (action) {
+ is AddressActionUi.HandleUserInput -> state
+ is AddressActionUi.SetTruncateHandler -> state.copy(truncateHandler = action.handler)
+ is AddressActionUi.TruncateOrRestore -> {
+ val value = if (action.truncate) state.truncatedFieldValue ?: "" else state.normalFieldValue ?: ""
+ state.copy(viewFieldValue = state.viewFieldValue.copy(value = value))
+ }
+ is AddressActionUi.PasteAddress -> return sendState
+ is AddressActionUi.CheckClipboard -> return sendState
+ is AddressActionUi.CheckAddress -> return sendState
+ }
+ return updateLastState(sendState.copy(addressState = result), result)
+ }
+
+ private fun handleAction(action: AddressVerifyAction, sendState: SendState, state: AddressState): SendState {
+ val result = when (action) {
+ is AddressVerification.SetWalletAddress -> {
+ state.copy(
+ viewFieldValue = InputViewValue(action.address, action.isUserInput),
+ normalFieldValue = action.address,
+ truncatedFieldValue = state.truncate(action.address),
+ destinationWalletAddress = action.address,
+ error = null,
+ )
+ }
+ is AddressVerifyAction.ChangePasteBtnEnableState -> state.copy(pasteIsEnabled = action.isEnabled)
+ is AddressVerification.SetAddressError -> state.copy(error = action.error, destinationWalletAddress = null)
+ }
+ return updateLastState(sendState.copy(addressState = result), result)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/SendScreenReducer.kt b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/SendScreenReducer.kt
index 4134e8c148..463b0dcaea 100644
--- a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/SendScreenReducer.kt
+++ b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/SendScreenReducer.kt
@@ -25,7 +25,7 @@ object SendScreenReducer {
val reducer: SendInternalReducer = when (action) {
is PrepareSendScreen -> PrepareSendScreenStatesReducer()
- is AddressPayIdActionUi, is AddressPayIdVerifyAction -> AddressPayIdReducer()
+ is AddressActionUi, is AddressVerifyAction -> AddressReducer()
is TransactionExtrasAction -> TransactionExtrasReducer()
is AmountActionUi, is AmountAction -> AmountReducer()
is FeeActionUi, is FeeAction -> FeeReducer()
@@ -71,7 +71,7 @@ private class SendReducer : SendInternalReducer {
amountState = state.amountState.copy(
inputIsEnabled = false,
),
- addressPayIdState = state.addressPayIdState.copy(
+ addressState = state.addressState.copy(
inputIsEnabled = false,
),
)
diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/states/AddressPayIdState.kt b/app/src/main/java/com/tangem/tap/features/send/redux/states/AddressState.kt
similarity index 90%
rename from app/src/main/java/com/tangem/tap/features/send/redux/states/AddressPayIdState.kt
rename to app/src/main/java/com/tangem/tap/features/send/redux/states/AddressState.kt
index 9f0851e06d..b6b65a595f 100644
--- a/app/src/main/java/com/tangem/tap/features/send/redux/states/AddressPayIdState.kt
+++ b/app/src/main/java/com/tangem/tap/features/send/redux/states/AddressState.kt
@@ -2,17 +2,16 @@ package com.tangem.tap.features.send.redux.states
import androidx.core.text.isDigitsOnly
import com.tangem.blockchain.blockchains.stellar.StellarMemo
-import com.tangem.tap.features.send.redux.AddressPayIdVerifyAction
+import com.tangem.tap.features.send.redux.AddressVerifyAction
import java.math.BigInteger
-data class AddressPayIdState(
+data class AddressState(
val viewFieldValue: InputViewValue = InputViewValue(""),
val normalFieldValue: String? = null,
val truncatedFieldValue: String? = null,
val destinationWalletAddress: String? = null,
- val error: AddressPayIdVerifyAction.Error? = null,
+ val error: AddressVerifyAction.Error? = null,
val truncateHandler: ((String) -> String)? = null,
- val sendingToPayIdEnabled: Boolean = false,
val pasteIsEnabled: Boolean = false,
val inputIsEnabled: Boolean = true,
) : SendScreenState {
@@ -22,8 +21,6 @@ data class AddressPayIdState(
fun truncate(value: String): String = truncateHandler?.invoke(value) ?: value
fun isReady(): Boolean = error == null && destinationWalletAddress?.isNotEmpty() ?: false
-
- fun isPayIdState(): Boolean = destinationWalletAddress != null && destinationWalletAddress != normalFieldValue
}
data class TransactionExtrasState(
@@ -98,11 +95,7 @@ data class BinanceMemoState(
val viewFieldValue: InputViewValue = InputViewValue(""),
val memo: BigInteger? = null,
val error: TransactionExtraError? = null,
-) {
- companion object {
- val MAX_NUMBER: BigInteger = BigInteger("FFFFFFFFFFFFFFFF", 16)
- }
-}
+)
// tag must contains only digits
data class XrpDestinationTagState(
diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/states/SendState.kt b/app/src/main/java/com/tangem/tap/features/send/redux/states/SendState.kt
index 6a47e2d342..8400f07c87 100644
--- a/app/src/main/java/com/tangem/tap/features/send/redux/states/SendState.kt
+++ b/app/src/main/java/com/tangem/tap/features/send/redux/states/SendState.kt
@@ -34,7 +34,7 @@ data class SendState(
val coinConverter: CurrencyConverter? = null,
val tokenConverter: CurrencyConverter? = null,
val lastChangedStates: LinkedHashSet = linkedSetOf(),
- val addressPayIdState: AddressPayIdState = AddressPayIdState(),
+ val addressState: AddressState = AddressState(),
val transactionExtrasState: TransactionExtrasState = TransactionExtrasState(),
val amountState: AmountState = AmountState(),
val feeState: FeeState = FeeState(),
@@ -52,7 +52,7 @@ data class SendState(
MainCurrencyType.CRYPTO -> amountState.amountToExtract?.decimals ?: 0
}
- fun convertFiatToCoin(value: BigDecimal): BigDecimal {
+ private fun convertFiatToCoin(value: BigDecimal): BigDecimal {
return if (!this.coinIsConvertible()) value else coinConverter!!.toCrypto(value)
}
@@ -60,14 +60,14 @@ data class SendState(
return if (!this.tokenIsConvertible()) value else tokenConverter!!.toCrypto(value)
}
- fun convertCoinToFiat(value: BigDecimal, scaleWithPrecision: Boolean = false): BigDecimal {
+ private fun convertCoinToFiat(value: BigDecimal, scaleWithPrecision: Boolean = false): BigDecimal {
if (!this.coinIsConvertible()) return value
val converter = coinConverter!!
return if (!scaleWithPrecision) converter.toFiat(value) else converter.toFiatWithPrecision(value)
}
- fun convertTokenToFiat(value: BigDecimal, scaleWithPrecision: Boolean = false): BigDecimal {
+ private fun convertTokenToFiat(value: BigDecimal, scaleWithPrecision: Boolean = false): BigDecimal {
if (!this.tokenIsConvertible()) return value
val converter = tokenConverter!!
@@ -107,13 +107,13 @@ data class SendState(
}
companion object {
- fun addressPayIdIsReady(): Boolean = store.state.sendState.addressPayIdState.isReady()
+ private fun addressIsReady(): Boolean = store.state.sendState.addressState.isReady()
- fun amountIsReady(): Boolean = store.state.sendState.amountState.isReady()
+ private fun amountIsReady(): Boolean = store.state.sendState.amountState.isReady()
- fun isReadyToRequestFee(): Boolean = addressPayIdIsReady() && amountIsReady()
+ fun isReadyToRequestFee(): Boolean = addressIsReady() && amountIsReady()
- fun isReadyToSend(): Boolean = addressPayIdIsReady() && amountIsReady() &&
+ fun isReadyToSend(): Boolean = addressIsReady() && amountIsReady() &&
store.state.sendState.feeState.isReady()
}
}
diff --git a/app/src/main/java/com/tangem/tap/features/send/ui/SendFragment.kt b/app/src/main/java/com/tangem/tap/features/send/ui/SendFragment.kt
index 64c4fc53a7..748ecacb4b 100644
--- a/app/src/main/java/com/tangem/tap/features/send/ui/SendFragment.kt
+++ b/app/src/main/java/com/tangem/tap/features/send/ui/SendFragment.kt
@@ -17,6 +17,7 @@ import by.kirich1409.viewbindingdelegate.viewBinding
import com.google.android.material.textfield.TextInputEditText
import com.tangem.Message
import com.tangem.core.analytics.Analytics
+import com.tangem.core.navigation.NavigationAction
import com.tangem.sdk.extensions.hideSoftKeyboard
import com.tangem.tap.common.KeyboardObserver
import com.tangem.tap.common.analytics.events.Token
@@ -25,7 +26,6 @@ import com.tangem.tap.common.extensions.getFromClipboard
import com.tangem.tap.common.extensions.setOnImeActionListener
import com.tangem.tap.common.qrCodeScan.ScanQrCodeActivity
import com.tangem.tap.common.recyclerView.SpaceItemDecoration
-import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.common.snackBar.MaxAmountSnackbar
import com.tangem.tap.common.text.truncateMiddleWith
import com.tangem.tap.common.toggleWidget.IndeterminateProgressButtonWidget
@@ -33,7 +33,7 @@ import com.tangem.tap.common.toggleWidget.ViewStateWidget
import com.tangem.tap.features.BaseStoreFragment
import com.tangem.tap.features.addBackPressHandler
import com.tangem.tap.features.send.redux.*
-import com.tangem.tap.features.send.redux.AddressPayIdActionUi.*
+import com.tangem.tap.features.send.redux.AddressActionUi.*
import com.tangem.tap.features.send.redux.AmountActionUi.*
import com.tangem.tap.features.send.redux.FeeActionUi.*
import com.tangem.tap.features.send.redux.states.FeeType
@@ -80,7 +80,7 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) {
etAmountToSend = view.findViewById(R.id.etAmountToSend)
initSendButtonStates()
- setupAddressOrPayIdLayout()
+ setupAddressLayout()
setupTransactionExtrasLayout()
setupAmountLayout()
setupFeeLayout()
@@ -99,14 +99,14 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) {
sendBtn = IndeterminateProgressButtonWidget(btnSend, progress)
}
- private fun setupAddressOrPayIdLayout() = with(binding.lSendAddressPayid) {
- store.dispatch(SetTruncateHandler { etAddressOrPayId.truncateMiddleWith(it, "...") })
+ private fun setupAddressLayout() = with(binding.lSendAddress) {
+ store.dispatch(SetTruncateHandler { etAddress.truncateMiddleWith(it, "...") })
store.dispatch(CheckClipboard(requireContext().getFromClipboard()?.toString()))
- etAddressOrPayId.apply {
+ etAddress.apply {
setOnSystemPasteButtonClickListener {
store.dispatch(
- PasteAddressPayId(
+ PasteAddress(
data = requireContext().getFromClipboard()?.toString() ?: "",
sourceType = Token.Send.AddressEntered.SourceType.PastePopup,
),
@@ -119,9 +119,9 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) {
inputtedTextAsFlow()
.debounce(EDIT_TEXT_INPUT_DEBOUNCE)
- .filter { store.state.sendState.addressPayIdState.viewFieldValue.value != it }
+ .filter { store.state.sendState.addressState.viewFieldValue.value != it }
.onEach {
- store.dispatch(AddressPayIdActionUi.HandleUserInput(it))
+ store.dispatch(AddressActionUi.HandleUserInput(it))
}
.launchIn(mainScope)
}
@@ -129,12 +129,12 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) {
imvPaste.setOnClickListener {
Analytics.send(Token.Send.ButtonPaste())
store.dispatch(
- PasteAddressPayId(
+ PasteAddress(
data = requireContext().getFromClipboard()?.toString() ?: "",
sourceType = Token.Send.AddressEntered.SourceType.PasteButton,
),
)
- store.dispatch(TruncateOrRestore(!etAddressOrPayId.isFocused))
+ store.dispatch(TruncateOrRestore(!etAddress.isFocused))
}
imvQrCode.setOnClickListener {
Analytics.send(Token.Send.ButtonQRCode())
@@ -145,7 +145,7 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) {
}
}
- private fun setupTransactionExtrasLayout() = with(binding.lSendAddressPayid) {
+ private fun setupTransactionExtrasLayout() = with(binding.lSendAddress) {
// TODO: [REDACTED_TASK_KEY]
etXlmMemo.inputtedTextAsFlow()
.debounce(EDIT_TEXT_INPUT_DEBOUNCE)
@@ -202,15 +202,15 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) {
// Delayed launch is needed in order for the UI to be drawn and to process the sent events.
// If do not use the delay, then etAmount error field is not displayed when
// inserting an incorrect amount by shareUri
- binding.lSendAddressPayid.imvQrCode.postDelayed(
+ binding.lSendAddress.imvQrCode.postDelayed(
{
store.dispatch(
- PasteAddressPayId(
+ PasteAddress(
data = scannedCode,
sourceType = Token.Send.AddressEntered.SourceType.QRCode,
),
)
- store.dispatch(TruncateOrRestore(!binding.lSendAddressPayid.etAddressOrPayId.isFocused))
+ store.dispatch(TruncateOrRestore(!binding.lSendAddress.etAddress.isFocused))
},
200,
)
diff --git a/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt b/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt
index 12f16a0274..7c12e82496 100644
--- a/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt
+++ b/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt
@@ -7,30 +7,15 @@ import android.view.View
import android.view.ViewGroup
import androidx.core.text.bold
import com.tangem.common.extensions.remove
-import com.tangem.tap.common.extensions.beginDelayedTransition
-import com.tangem.tap.common.extensions.enableError
-import com.tangem.tap.common.extensions.getColor
-import com.tangem.tap.common.extensions.getString
-import com.tangem.tap.common.extensions.hide
-import com.tangem.tap.common.extensions.show
-import com.tangem.tap.common.extensions.update
+import com.tangem.tap.common.extensions.*
import com.tangem.tap.common.redux.getMessageString
import com.tangem.tap.common.text.DecimalDigitsInputFilter
import com.tangem.tap.domain.MultiMessageError
import com.tangem.tap.domain.assembleErrors
import com.tangem.tap.features.BaseStoreFragment
-import com.tangem.tap.features.send.redux.AddressPayIdVerifyAction.Error
+import com.tangem.tap.features.send.redux.AddressVerifyAction.Error
import com.tangem.tap.features.send.redux.SendAction
-import com.tangem.tap.features.send.redux.states.AddressPayIdState
-import com.tangem.tap.features.send.redux.states.AmountState
-import com.tangem.tap.features.send.redux.states.FeeState
-import com.tangem.tap.features.send.redux.states.MainCurrencyType
-import com.tangem.tap.features.send.redux.states.ReceiptLayoutType
-import com.tangem.tap.features.send.redux.states.ReceiptState
-import com.tangem.tap.features.send.redux.states.SendState
-import com.tangem.tap.features.send.redux.states.StateId
-import com.tangem.tap.features.send.redux.states.TransactionExtraError
-import com.tangem.tap.features.send.redux.states.TransactionExtrasState
+import com.tangem.tap.features.send.redux.states.*
import com.tangem.tap.features.send.ui.FeeUiHelper
import com.tangem.tap.features.send.ui.SendFragment
import com.tangem.tap.features.send.ui.dialogs.KaspaWarningDialog
@@ -61,7 +46,7 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber
lastChangedStates.forEach {
when (it) {
StateId.SEND_SCREEN -> handleSendScreen(fg, state)
- StateId.ADDRESS_PAY_ID -> handleAddressPayIdState(fg, state.addressPayIdState)
+ StateId.ADDRESS_PAY_ID -> handleAddressState(fg, state.addressState)
StateId.TRANSACTION_EXTRAS -> handleTransactionExtrasState(fg, state.transactionExtrasState)
StateId.AMOUNT -> handleAmountState(fg, state.amountState)
StateId.FEE -> handleFeeState(fg, state.feeState)
@@ -72,7 +57,7 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber
@Suppress("ComplexMethod")
private fun handleTransactionExtrasState(fg: SendFragment, infoState: TransactionExtrasState) =
- with(fg.binding.lSendAddressPayid) {
+ with(fg.binding.lSendAddress) {
fun showView(view: View, info: Any?) {
view.show(info != null)
}
@@ -192,13 +177,10 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber
)
}
- private fun handleAddressPayIdState(fg: SendFragment, state: AddressPayIdState) =
- with(fg.binding.lSendAddressPayid) {
+ private fun handleAddressState(fg: SendFragment, state: AddressState) {
+ with(fg.binding.lSendAddress) {
fun parseError(context: Context, error: Error?): String? {
val resId = when (error) {
- Error.PAY_ID_UNSUPPORTED_BY_BLOCKCHAIN -> R.string.send_error_payid_unsupported_by_blockchain
- Error.PAY_ID_NOT_REGISTERED -> R.string.send_error_payid_not_registered
- Error.PAY_ID_REQUEST_FAILED -> R.string.send_error_payid_request_failed
Error.ADDRESS_INVALID_OR_UNSUPPORTED_BY_BLOCKCHAIN -> R.string.send_validation_invalid_address
Error.ADDRESS_SAME_AS_WALLET -> R.string.send_error_address_same_as_wallet
else -> null
@@ -208,8 +190,8 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber
imvPaste.isEnabled = state.pasteIsEnabled
- val et = etAddressOrPayId
- val til = tilAddressOrPayId
+ val et = etAddress
+ val til = tilAddress
val parsedError = parseError(til.context, state.error)
til.isEnabled = state.inputIsEnabled
@@ -218,19 +200,15 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber
flPaste.show(state.inputIsEnabled)
flQrCode.show(state.inputIsEnabled)
- val hintResId = if (state.sendingToPayIdEnabled) {
- R.string.send_destination_hint_address_payid
- } else {
- R.string.send_destination_hint_address
- }
- til.hint = til.getString(hintResId)
+ til.hint = til.getString(R.string.send_destination_hint_address)
til.error = parsedError
til.isErrorEnabled = parsedError != null
til.helperText = state.destinationWalletAddress
- til.isHelperTextEnabled = state.isPayIdState() && parsedError == null
+ til.isHelperTextEnabled = parsedError == null
if (!state.viewFieldValue.isFromUserInput) et.update(state.viewFieldValue.value)
}
+ }
private fun handleAmountState(fg: SendFragment, state: AmountState) = with(fg.binding.lSendAmount) {
if (state.error != null) {
diff --git a/app/src/main/java/com/tangem/tap/features/shop/redux/ShopMiddleware.kt b/app/src/main/java/com/tangem/tap/features/shop/redux/ShopMiddleware.kt
index 3af546cab6..f049ef01b6 100644
--- a/app/src/main/java/com/tangem/tap/features/shop/redux/ShopMiddleware.kt
+++ b/app/src/main/java/com/tangem/tap/features/shop/redux/ShopMiddleware.kt
@@ -1,12 +1,12 @@
package com.tangem.tap.features.shop.redux
import com.tangem.core.analytics.Analytics
+import com.tangem.core.navigation.AppScreen
+import com.tangem.core.navigation.NavigationAction
import com.tangem.tap.common.analytics.events.Shop
import com.tangem.tap.common.extensions.dispatchOnMain
import com.tangem.tap.common.extensions.dispatchOpenUrl
import com.tangem.tap.common.redux.AppState
-import com.tangem.tap.common.redux.navigation.AppScreen
-import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.scope
import com.tangem.tap.shopService
import com.tangem.tap.store
diff --git a/app/src/main/java/com/tangem/tap/features/shop/ui/ShopFragment.kt b/app/src/main/java/com/tangem/tap/features/shop/ui/ShopFragment.kt
index 56ffe54b0f..4af0db0285 100644
--- a/app/src/main/java/com/tangem/tap/features/shop/ui/ShopFragment.kt
+++ b/app/src/main/java/com/tangem/tap/features/shop/ui/ShopFragment.kt
@@ -11,12 +11,12 @@ import android.view.inputmethod.InputMethodManager
import androidx.activity.OnBackPressedCallback
import androidx.fragment.app.viewModels
import by.kirich1409.viewbindingdelegate.viewBinding
+import com.tangem.core.navigation.NavigationAction
import com.tangem.tap.common.GlobalLayoutStateHandler
import com.tangem.tap.common.KeyboardObserver
import com.tangem.tap.common.extensions.getQuantityString
import com.tangem.tap.common.extensions.hide
import com.tangem.tap.common.extensions.show
-import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.common.shop.data.ProductType
import com.tangem.tap.features.BaseStoreFragment
import com.tangem.tap.features.shop.presentation.ShopViewModel
diff --git a/app/src/main/java/com/tangem/tap/features/sprinklr/ui/SprinklrViewModel.kt b/app/src/main/java/com/tangem/tap/features/sprinklr/ui/SprinklrViewModel.kt
index 87c033582a..a6cf3abe13 100644
--- a/app/src/main/java/com/tangem/tap/features/sprinklr/ui/SprinklrViewModel.kt
+++ b/app/src/main/java/com/tangem/tap/features/sprinklr/ui/SprinklrViewModel.kt
@@ -2,8 +2,8 @@ package com.tangem.tap.features.sprinklr.ui
import androidx.lifecycle.ViewModel
import com.google.accompanist.web.WebContent
+import com.tangem.core.navigation.NavigationAction
import com.tangem.tap.common.extensions.dispatchOnMain
-import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.features.sprinklr.redux.SprinklrState
import com.tangem.tap.store
import kotlinx.coroutines.flow.MutableStateFlow
diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/router/DefaultTokensListRouter.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/router/DefaultTokensListRouter.kt
index cbfe64e505..4c390f27d6 100644
--- a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/router/DefaultTokensListRouter.kt
+++ b/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/router/DefaultTokensListRouter.kt
@@ -1,10 +1,10 @@
package com.tangem.tap.features.tokens.impl.presentation.router
+import com.tangem.core.navigation.AppScreen
+import com.tangem.core.navigation.NavigationAction
import com.tangem.tap.common.extensions.dispatchDialogShow
import com.tangem.tap.common.extensions.dispatchNotification
import com.tangem.tap.common.redux.AppDialog
-import com.tangem.tap.common.redux.navigation.AppScreen
-import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.features.customtoken.api.featuretoggles.CustomTokenFeatureToggles
import com.tangem.tap.features.tokens.legacy.redux.TokensAction
import com.tangem.tap.features.wallet.redux.models.WalletDialog
diff --git a/app/src/main/java/com/tangem/tap/features/tokens/legacy/redux/TokensMiddleware.kt b/app/src/main/java/com/tangem/tap/features/tokens/legacy/redux/TokensMiddleware.kt
index 70a7e1b2cd..c62a8053d9 100644
--- a/app/src/main/java/com/tangem/tap/features/tokens/legacy/redux/TokensMiddleware.kt
+++ b/app/src/main/java/com/tangem/tap/features/tokens/legacy/redux/TokensMiddleware.kt
@@ -9,6 +9,8 @@ import com.tangem.common.extensions.guard
import com.tangem.common.extensions.toMapKey
import com.tangem.common.flatMap
import com.tangem.core.analytics.Analytics
+import com.tangem.core.navigation.AppScreen
+import com.tangem.core.navigation.NavigationAction
import com.tangem.crypto.hdWallet.DerivationPath
import com.tangem.domain.DomainWrapped
import com.tangem.domain.common.TapWorkarounds.derivationStyle
@@ -25,8 +27,6 @@ import com.tangem.tap.common.extensions.dispatchDebugErrorNotification
import com.tangem.tap.common.extensions.dispatchOnMain
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.common.redux.global.GlobalAction
-import com.tangem.tap.common.redux.navigation.AppScreen
-import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.domain.TapError
import com.tangem.tap.domain.model.WalletDataModel
import com.tangem.tap.features.wallet.models.Currency
diff --git a/app/src/main/java/com/tangem/tap/features/wallet/models/Currency.kt b/app/src/main/java/com/tangem/tap/features/wallet/models/Currency.kt
index 71cef96432..4b82889e22 100644
--- a/app/src/main/java/com/tangem/tap/features/wallet/models/Currency.kt
+++ b/app/src/main/java/com/tangem/tap/features/wallet/models/Currency.kt
@@ -2,11 +2,11 @@ package com.tangem.tap.features.wallet.models
import com.tangem.blockchain.common.DerivationStyle
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
+import com.tangem.domain.common.BlockchainNetwork
import com.tangem.domain.common.extensions.fromNetworkId
import com.tangem.domain.common.extensions.toCoinId
import com.tangem.domain.features.addCustomToken.CustomCurrency
import com.tangem.tap.common.redux.global.CryptoCurrencyName
-import com.tangem.tap.domain.tokens.models.BlockchainNetwork
import com.tangem.blockchain.common.Blockchain as SdkBlockchain
import com.tangem.blockchain.common.Token as SdkToken
diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt
index 8db98a4ee0..3f73a94c11 100644
--- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt
+++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt
@@ -4,17 +4,17 @@ import android.content.Context
import com.tangem.blockchain.common.Amount
import com.tangem.blockchain.common.address.AddressType
import com.tangem.core.analytics.AnalyticsEvent
-import com.tangem.domain.common.util.UserWalletId
+import com.tangem.domain.common.BlockchainNetwork
import com.tangem.domain.models.scan.CardDTO
+import com.tangem.domain.wallets.models.UserWallet
+import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.tap.common.entities.FiatCurrency
import com.tangem.tap.common.redux.NotificationAction
import com.tangem.tap.domain.TapError
import com.tangem.tap.domain.configurable.warningMessage.WarningMessage
import com.tangem.tap.domain.model.TotalFiatBalance
-import com.tangem.tap.domain.model.UserWallet
import com.tangem.tap.domain.model.WalletDataModel
import com.tangem.tap.domain.model.WalletStoreModel
-import com.tangem.tap.domain.tokens.models.BlockchainNetwork
import com.tangem.tap.features.wallet.models.Currency
import com.tangem.tap.features.wallet.redux.models.WalletDialog
import com.tangem.wallet.R
diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt
index 9c1feed6b4..2135a4ab7d 100644
--- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt
+++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt
@@ -4,6 +4,7 @@ import android.graphics.Bitmap
import com.tangem.blockchain.common.AmountType
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.WalletManager
+import com.tangem.domain.common.BlockchainNetwork
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.tap.common.entities.Button
import com.tangem.tap.common.redux.global.CryptoCurrencyName
@@ -12,7 +13,6 @@ import com.tangem.tap.domain.configurable.warningMessage.WarningMessage
import com.tangem.tap.domain.model.TotalFiatBalance
import com.tangem.tap.domain.model.WalletDataModel
import com.tangem.tap.domain.model.WalletStoreModel
-import com.tangem.tap.domain.tokens.models.BlockchainNetwork
import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsState
import com.tangem.tap.features.wallet.models.Currency
import com.tangem.tap.store
diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/MultiWalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/MultiWalletMiddleware.kt
index d86a41c389..d008d1b2e0 100644
--- a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/MultiWalletMiddleware.kt
+++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/MultiWalletMiddleware.kt
@@ -4,6 +4,9 @@ import com.tangem.common.doOnSuccess
import com.tangem.common.extensions.guard
import com.tangem.common.flatMap
import com.tangem.core.analytics.Analytics
+import com.tangem.core.navigation.AppScreen
+import com.tangem.core.navigation.NavigationAction
+import com.tangem.domain.wallets.models.UserWallet
import com.tangem.tap.common.analytics.events.AnalyticsParam
import com.tangem.tap.common.analytics.events.Token.ButtonRemoveToken
import com.tangem.tap.common.extensions.addContext
@@ -11,10 +14,7 @@ import com.tangem.tap.common.extensions.dispatchDialogShow
import com.tangem.tap.common.extensions.dispatchErrorNotification
import com.tangem.tap.common.extensions.dispatchWithMain
import com.tangem.tap.common.redux.global.GlobalAction
-import com.tangem.tap.common.redux.navigation.AppScreen
-import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.domain.TapError
-import com.tangem.tap.domain.model.UserWallet
import com.tangem.tap.domain.scanCard.ScanCardProcessor
import com.tangem.tap.features.wallet.redux.WalletAction
import com.tangem.tap.features.wallet.redux.WalletState
diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/TradeCryptoMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/TradeCryptoMiddleware.kt
index 0c56d30f51..fbb76f391a 100644
--- a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/TradeCryptoMiddleware.kt
+++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/TradeCryptoMiddleware.kt
@@ -6,6 +6,8 @@ import com.tangem.blockchain.blockchains.ethereum.EthereumWalletManager
import com.tangem.blockchain.common.AmountType
import com.tangem.common.extensions.guard
import com.tangem.core.analytics.Analytics
+import com.tangem.core.navigation.AppScreen
+import com.tangem.core.navigation.NavigationAction
import com.tangem.domain.common.extensions.toCoinId
import com.tangem.domain.common.extensions.toNetworkId
import com.tangem.feature.swap.presentation.SwapFragment
@@ -15,8 +17,6 @@ import com.tangem.tap.common.extensions.dispatchDebugErrorNotification
import com.tangem.tap.common.extensions.dispatchOnMain
import com.tangem.tap.common.extensions.dispatchOpenUrl
import com.tangem.tap.common.redux.AppState
-import com.tangem.tap.common.redux.navigation.AppScreen
-import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.domain.tokens.getIconUrl
import com.tangem.tap.features.demo.DemoHelper
import com.tangem.tap.features.home.RUSSIA_COUNTRY_CODE
diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt
index d7a0da7703..2bdd72972f 100644
--- a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt
+++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt
@@ -9,6 +9,8 @@ import com.tangem.common.CompletionResult
import com.tangem.common.doOnSuccess
import com.tangem.common.extensions.guard
import com.tangem.core.analytics.Analytics
+import com.tangem.core.navigation.AppScreen
+import com.tangem.core.navigation.NavigationAction
import com.tangem.datasource.connection.NetworkConnectionManager
import com.tangem.tap.*
import com.tangem.tap.common.analytics.events.AnalyticsParam
@@ -18,8 +20,6 @@ import com.tangem.tap.common.analytics.events.Token
import com.tangem.tap.common.extensions.*
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.common.redux.global.GlobalAction
-import com.tangem.tap.common.redux.navigation.AppScreen
-import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.domain.TapError
import com.tangem.tap.domain.model.WalletDataModel
import com.tangem.tap.domain.model.WalletStoreModel
diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt
index afee65593c..09946690a4 100644
--- a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt
+++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt
@@ -22,6 +22,7 @@ import com.badoo.mvicore.modelWatcher
import com.tangem.common.doOnResult
import com.tangem.common.extensions.guard
import com.tangem.core.analytics.Analytics
+import com.tangem.core.navigation.NavigationAction
import com.tangem.domain.common.TapWorkarounds.derivationStyle
import com.tangem.domain.common.extensions.withMainContext
import com.tangem.feature.swap.api.SwapFeatureToggleManager
@@ -41,7 +42,6 @@ import com.tangem.tap.common.extensions.show
import com.tangem.tap.common.extensions.toQrCode
import com.tangem.tap.common.recyclerView.SpaceItemDecoration
import com.tangem.tap.common.redux.AppState
-import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.common.utils.SafeStoreSubscriber
import com.tangem.tap.domain.model.WalletDataModel
import com.tangem.tap.features.wallet.models.Currency
diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt
index 47d07b91b0..af1d2100aa 100644
--- a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt
+++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt
@@ -8,7 +8,9 @@ import android.view.View
import androidx.activity.OnBackPressedCallback
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.runtime.mutableStateOf
+import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.fragment.app.Fragment
+import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.flowWithLifecycle
@@ -21,18 +23,22 @@ import coil.load
import coil.size.Scale
import com.badoo.mvicore.modelWatcher
import com.tangem.core.analytics.Analytics
+import com.tangem.core.navigation.AppScreen
+import com.tangem.core.navigation.NavigationAction
import com.tangem.core.ui.fragments.setStatusBarColor
+import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.utils.OneTouchClickListener
import com.tangem.datasource.connection.NetworkConnectionManager
+import com.tangem.feature.learn2earn.presentation.Learn2earnViewModel
+import com.tangem.feature.learn2earn.presentation.ui.Learn2earnMainPageScreen
import com.tangem.feature.swap.api.SwapFeatureToggleManager
import com.tangem.feature.swap.domain.SwapInteractor
import com.tangem.tap.MainActivity
import com.tangem.tap.common.analytics.events.Portfolio
+import com.tangem.tap.common.extensions.beginDelayedTransition
import com.tangem.tap.common.extensions.show
import com.tangem.tap.common.recyclerView.SpaceItemDecoration
import com.tangem.tap.common.redux.global.GlobalAction
-import com.tangem.tap.common.redux.navigation.AppScreen
-import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.common.utils.SafeStoreSubscriber
import com.tangem.tap.domain.configurable.warningMessage.WarningMessage
import com.tangem.tap.domain.statePrinter.printScanResponseState
@@ -73,6 +79,7 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), SafeStoreSubscriber()
private val viewModel by viewModels()
private val totalBalanceWatcher = modelWatcher {
@@ -102,6 +109,7 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), SafeStoreSubscriber) {
diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletViewModel.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletViewModel.kt
index ded1be23f3..b94cc9de26 100644
--- a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletViewModel.kt
+++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletViewModel.kt
@@ -6,27 +6,19 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.domain.common.util.cardTypesResolver
+import com.tangem.domain.wallets.legacy.UserWalletsListManager
import com.tangem.tap.common.analytics.converters.ParamCardCurrencyConverter
import com.tangem.tap.common.analytics.events.Basic
import com.tangem.tap.common.analytics.events.MainScreen
import com.tangem.tap.common.extensions.dispatchOnMain
import com.tangem.tap.domain.model.TotalFiatBalance
-import com.tangem.tap.domain.userWalletList.UserWalletsListManager
import com.tangem.tap.features.wallet.redux.WalletAction
import com.tangem.tap.features.wallet.ui.analytics.WalletAnalyticsEventsMapper
import com.tangem.tap.store
import com.tangem.tap.walletStoresManager
import dagger.hilt.android.lifecycle.HiltViewModel
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.FlowPreview
-import kotlinx.coroutines.Job
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.debounce
-import kotlinx.coroutines.flow.flatMapLatest
-import kotlinx.coroutines.flow.launchIn
-import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.launch
+import kotlinx.coroutines.*
+import kotlinx.coroutines.flow.*
import org.rekotlin.StoreSubscriber
import javax.inject.Inject
@@ -71,6 +63,7 @@ internal class WalletViewModel @Inject constructor(
currency = currency,
batch = scanResponse.card.batchId,
signInType = signInType,
+ walletsCount = store.state.globalState.userWalletsListManager?.walletsCount.toString(),
),
)
}
diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/RussianCardholdersWarningBottomSheetDialog.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/RussianCardholdersWarningBottomSheetDialog.kt
index 9c8d5997b9..b7ec4ee4a1 100644
--- a/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/RussianCardholdersWarningBottomSheetDialog.kt
+++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/RussianCardholdersWarningBottomSheetDialog.kt
@@ -5,10 +5,10 @@ import android.os.Bundle
import android.view.LayoutInflater
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.tangem.core.analytics.Analytics
+import com.tangem.core.navigation.NavigationAction
import com.tangem.tap.common.analytics.events.Token
import com.tangem.tap.common.extensions.dispatchDialogHide
import com.tangem.tap.common.extensions.dispatchOpenUrl
-import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.features.wallet.redux.WalletAction
import com.tangem.tap.features.wallet.redux.models.WalletDialog
import com.tangem.tap.store
@@ -17,8 +17,7 @@ import com.tangem.wallet.databinding.DialogRussiansCardholdersWarningBinding
class RussianCardholdersWarningBottomSheetDialog(
context: Context,
private val dialogData: WalletDialog.RussianCardholdersWarningDialog.Data?,
-) : BottomSheetDialog
-(context) {
+) : BottomSheetDialog(context) {
private var binding: DialogRussiansCardholdersWarningBinding? = null
diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/test/TestWallet.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/test/TestWallet.kt
index 5b3dab3e8b..188cf35d91 100644
--- a/app/src/main/java/com/tangem/tap/features/wallet/ui/test/TestWallet.kt
+++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/test/TestWallet.kt
@@ -5,10 +5,10 @@ import com.tangem.blockchain.common.AmountType
import com.tangem.blockchain.common.Token
import com.tangem.blockchain.common.WalletManager
import com.tangem.common.extensions.guard
+import com.tangem.domain.common.BlockchainNetwork
import com.tangem.tap.common.TestAction
import com.tangem.tap.common.TestActions
import com.tangem.tap.common.extensions.dispatchDebugErrorNotification
-import com.tangem.tap.domain.tokens.models.BlockchainNetwork
import com.tangem.tap.features.wallet.redux.WalletAction
import com.tangem.tap.store
import java.math.BigDecimal
diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/utils/WalletDataOperations.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/utils/WalletDataOperations.kt
index 63de2cf579..3f72a34acb 100644
--- a/app/src/main/java/com/tangem/tap/features/wallet/ui/utils/WalletDataOperations.kt
+++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/utils/WalletDataOperations.kt
@@ -12,6 +12,7 @@ import com.tangem.tap.common.extensions.toFormattedCurrencyString
import com.tangem.tap.common.extensions.toFormattedFiatValue
import com.tangem.tap.domain.model.WalletDataModel
import com.tangem.tap.domain.model.WalletStoreModel
+import com.tangem.tap.features.wallet.models.PendingTransactionType
import com.tangem.tap.features.wallet.models.WalletWarning
import com.tangem.tap.features.wallet.redux.WalletMainButton
import com.tangem.tap.features.wallet.redux.utils.UNKNOWN_AMOUNT_SIGN
@@ -26,15 +27,14 @@ internal fun WalletDataModel.mainButton(blockchainAmount: BigDecimal): WalletMai
internal fun WalletDataModel.hasPendingTransactions(): Boolean {
// for now check pending ongoing only just for BTC, later test and add other utxo networks
- // disabled for release 4.8, test and enable in 4.9
- // val isBitcoinBlockchain =
- // currency.blockchain == Blockchain.Bitcoin || currency.blockchain == Blockchain.BitcoinTestnet
- // if (currency.isBlockchain() && isBitcoinBlockchain) {
- // val outgoingTransactions = status.pendingTransactions.filter {
- // it.type == PendingTransactionType.Outgoing
- // }
- // return outgoingTransactions.isEmpty()
- // }
+ val isBitcoinBlockchain =
+ currency.blockchain == Blockchain.Bitcoin || currency.blockchain == Blockchain.BitcoinTestnet
+ if (currency.isBlockchain() && isBitcoinBlockchain) {
+ val outgoingTransactions = status.pendingTransactions.filter {
+ it.type == PendingTransactionType.Outgoing
+ }
+ return outgoingTransactions.isEmpty()
+ }
return status.pendingTransactions.isEmpty()
}
@@ -98,7 +98,7 @@ internal fun WalletDataModel.getAvailableActions(
internal fun WalletDataModel.shouldShowMultipleAddress(): Boolean {
val listOfAddresses = walletAddresses?.list.orEmpty()
- return listOfAddresses.size > 1 && currency.blockchain != Blockchain.BitcoinCash
+ return listOfAddresses.size > 1
}
internal fun WalletDataModel.assembleWarnings(
diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/MultiWalletView.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/MultiWalletView.kt
index 421393fcb5..6dec677865 100644
--- a/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/MultiWalletView.kt
+++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/MultiWalletView.kt
@@ -4,6 +4,8 @@ import androidx.core.view.isVisible
import androidx.recyclerview.widget.LinearLayoutManager
import com.badoo.mvicore.modelWatcher
import com.tangem.core.analytics.Analytics
+import com.tangem.core.navigation.AppScreen
+import com.tangem.core.navigation.NavigationAction
import com.tangem.domain.common.TapWorkarounds.derivationStyle
import com.tangem.tap.common.analytics.events.MainScreen
import com.tangem.tap.common.analytics.events.Portfolio
@@ -11,8 +13,6 @@ import com.tangem.tap.common.entities.FiatCurrency
import com.tangem.tap.common.extensions.getQuantityString
import com.tangem.tap.common.extensions.hide
import com.tangem.tap.common.extensions.show
-import com.tangem.tap.common.redux.navigation.AppScreen
-import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.domain.model.TotalFiatBalance
import com.tangem.tap.features.tokens.legacy.redux.TokensAction
import com.tangem.tap.features.wallet.redux.ErrorType
diff --git a/app/src/main/java/com/tangem/tap/features/walletSelector/redux/UserWalletModel.kt b/app/src/main/java/com/tangem/tap/features/walletSelector/redux/UserWalletModel.kt
index b381b423c3..d1300ffa43 100644
--- a/app/src/main/java/com/tangem/tap/features/walletSelector/redux/UserWalletModel.kt
+++ b/app/src/main/java/com/tangem/tap/features/walletSelector/redux/UserWalletModel.kt
@@ -1,6 +1,6 @@
package com.tangem.tap.features.walletSelector.redux
-import com.tangem.domain.common.util.UserWalletId
+import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.tap.domain.model.TotalFiatBalance
data class UserWalletModel(
diff --git a/app/src/main/java/com/tangem/tap/features/walletSelector/redux/WalletSelectorAction.kt b/app/src/main/java/com/tangem/tap/features/walletSelector/redux/WalletSelectorAction.kt
index e997860d4e..9acb28b1d6 100644
--- a/app/src/main/java/com/tangem/tap/features/walletSelector/redux/WalletSelectorAction.kt
+++ b/app/src/main/java/com/tangem/tap/features/walletSelector/redux/WalletSelectorAction.kt
@@ -1,9 +1,9 @@
package com.tangem.tap.features.walletSelector.redux
import com.tangem.common.core.TangemError
-import com.tangem.domain.common.util.UserWalletId
+import com.tangem.domain.wallets.models.UserWallet
+import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.tap.common.entities.FiatCurrency
-import com.tangem.tap.domain.model.UserWallet
import com.tangem.tap.domain.model.WalletStoreModel
import org.rekotlin.Action
diff --git a/app/src/main/java/com/tangem/tap/features/walletSelector/redux/WalletSelectorMiddleware.kt b/app/src/main/java/com/tangem/tap/features/walletSelector/redux/WalletSelectorMiddleware.kt
index 3528a61c7a..00d1e687bb 100644
--- a/app/src/main/java/com/tangem/tap/features/walletSelector/redux/WalletSelectorMiddleware.kt
+++ b/app/src/main/java/com/tangem/tap/features/walletSelector/redux/WalletSelectorMiddleware.kt
@@ -3,8 +3,11 @@ package com.tangem.tap.features.walletSelector.redux
import com.tangem.common.*
import com.tangem.common.core.TangemSdkError
import com.tangem.core.analytics.Analytics
-import com.tangem.domain.common.util.UserWalletId
+import com.tangem.core.navigation.AppScreen
+import com.tangem.core.navigation.NavigationAction
import com.tangem.domain.models.scan.ScanResponse
+import com.tangem.domain.wallets.models.UserWallet
+import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.tap.*
import com.tangem.tap.common.analytics.events.AnalyticsParam
import com.tangem.tap.common.analytics.events.Basic
@@ -13,10 +16,7 @@ import com.tangem.tap.common.extensions.dispatchOnMain
import com.tangem.tap.common.extensions.dispatchWithMain
import com.tangem.tap.common.extensions.onUserWalletSelected
import com.tangem.tap.common.redux.AppState
-import com.tangem.tap.common.redux.navigation.AppScreen
-import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.domain.model.TotalFiatBalance
-import com.tangem.tap.domain.model.UserWallet
import com.tangem.tap.domain.model.WalletStoreModel
import com.tangem.tap.domain.model.builders.UserWalletBuilder
import com.tangem.tap.domain.model.builders.UserWalletIdBuilder
diff --git a/app/src/main/java/com/tangem/tap/features/walletSelector/redux/WalletSelectorReducer.kt b/app/src/main/java/com/tangem/tap/features/walletSelector/redux/WalletSelectorReducer.kt
index 2a8ace7ad3..13daba6567 100644
--- a/app/src/main/java/com/tangem/tap/features/walletSelector/redux/WalletSelectorReducer.kt
+++ b/app/src/main/java/com/tangem/tap/features/walletSelector/redux/WalletSelectorReducer.kt
@@ -2,9 +2,9 @@ package com.tangem.tap.features.walletSelector.redux
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.domain.models.scan.CardDTO
+import com.tangem.domain.wallets.models.UserWallet
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.domain.model.TotalFiatBalance
-import com.tangem.tap.domain.model.UserWallet
import org.rekotlin.Action
internal object WalletSelectorReducer {
diff --git a/app/src/main/java/com/tangem/tap/features/walletSelector/redux/WalletSelectorState.kt b/app/src/main/java/com/tangem/tap/features/walletSelector/redux/WalletSelectorState.kt
index 797cc04593..49e1f753a3 100644
--- a/app/src/main/java/com/tangem/tap/features/walletSelector/redux/WalletSelectorState.kt
+++ b/app/src/main/java/com/tangem/tap/features/walletSelector/redux/WalletSelectorState.kt
@@ -1,7 +1,7 @@
package com.tangem.tap.features.walletSelector.redux
import com.tangem.common.core.TangemError
-import com.tangem.domain.common.util.UserWalletId
+import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.tap.common.entities.FiatCurrency
import org.rekotlin.StateType
diff --git a/app/src/main/java/com/tangem/tap/features/walletSelector/ui/WalletSelectorScreenState.kt b/app/src/main/java/com/tangem/tap/features/walletSelector/ui/WalletSelectorScreenState.kt
index b2da2e5b5f..796c2eac3f 100644
--- a/app/src/main/java/com/tangem/tap/features/walletSelector/ui/WalletSelectorScreenState.kt
+++ b/app/src/main/java/com/tangem/tap/features/walletSelector/ui/WalletSelectorScreenState.kt
@@ -1,7 +1,7 @@
package com.tangem.tap.features.walletSelector.ui
import androidx.compose.runtime.Immutable
-import com.tangem.domain.common.util.UserWalletId
+import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.tap.features.details.ui.cardsettings.TextReference
import com.tangem.tap.features.walletSelector.ui.model.DialogModel
import com.tangem.tap.features.walletSelector.ui.model.MultiCurrencyUserWalletItem
diff --git a/app/src/main/java/com/tangem/tap/features/walletSelector/ui/WalletSelectorViewModel.kt b/app/src/main/java/com/tangem/tap/features/walletSelector/ui/WalletSelectorViewModel.kt
index c6339f9cd8..6fb9347118 100644
--- a/app/src/main/java/com/tangem/tap/features/walletSelector/ui/WalletSelectorViewModel.kt
+++ b/app/src/main/java/com/tangem/tap/features/walletSelector/ui/WalletSelectorViewModel.kt
@@ -4,7 +4,7 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.tangem.common.core.TangemError
import com.tangem.core.analytics.Analytics
-import com.tangem.domain.common.util.UserWalletId
+import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.tap.common.analytics.events.MyWallets
import com.tangem.tap.common.extensions.dispatchOnMain
import com.tangem.tap.domain.userWalletList.UserWalletsListError
diff --git a/app/src/main/java/com/tangem/tap/features/walletSelector/ui/components/MockData.kt b/app/src/main/java/com/tangem/tap/features/walletSelector/ui/components/MockData.kt
index c404c8890a..0099f47c84 100644
--- a/app/src/main/java/com/tangem/tap/features/walletSelector/ui/components/MockData.kt
+++ b/app/src/main/java/com/tangem/tap/features/walletSelector/ui/components/MockData.kt
@@ -1,6 +1,6 @@
package com.tangem.tap.features.walletSelector.ui.components
-import com.tangem.domain.common.util.UserWalletId
+import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.tap.features.walletSelector.ui.WalletSelectorScreenState
import com.tangem.tap.features.walletSelector.ui.model.MultiCurrencyUserWalletItem
import com.tangem.tap.features.walletSelector.ui.model.SingleCurrencyUserWalletItem
diff --git a/app/src/main/java/com/tangem/tap/features/walletSelector/ui/components/WallectSelectorScreenContent.kt b/app/src/main/java/com/tangem/tap/features/walletSelector/ui/components/WallectSelectorScreenContent.kt
index f0dd6b139b..472a4322ec 100644
--- a/app/src/main/java/com/tangem/tap/features/walletSelector/ui/components/WallectSelectorScreenContent.kt
+++ b/app/src/main/java/com/tangem/tap/features/walletSelector/ui/components/WallectSelectorScreenContent.kt
@@ -25,7 +25,7 @@ import com.tangem.core.ui.components.SecondaryButtonIconEnd
import com.tangem.core.ui.components.SpacerWMax
import com.tangem.core.ui.components.atoms.Hand
import com.tangem.core.ui.res.TangemTheme
-import com.tangem.domain.common.util.UserWalletId
+import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.tap.features.walletSelector.ui.WalletSelectorScreenState
import com.tangem.wallet.R
diff --git a/app/src/main/java/com/tangem/tap/features/walletSelector/ui/components/WalletItem.kt b/app/src/main/java/com/tangem/tap/features/walletSelector/ui/components/WalletItem.kt
index 03d505e048..305cfa6545 100644
--- a/app/src/main/java/com/tangem/tap/features/walletSelector/ui/components/WalletItem.kt
+++ b/app/src/main/java/com/tangem/tap/features/walletSelector/ui/components/WalletItem.kt
@@ -4,16 +4,7 @@ import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.combinedClickable
-import androidx.compose.foundation.layout.Arrangement
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.RowScope
-import androidx.compose.foundation.layout.height
-import androidx.compose.foundation.layout.heightIn
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.size
-import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.Divider
import androidx.compose.material.Icon
@@ -39,7 +30,7 @@ import com.tangem.core.ui.components.SpacerH2
import com.tangem.core.ui.components.SpacerW6
import com.tangem.core.ui.components.SpacerW8
import com.tangem.core.ui.res.TangemTheme
-import com.tangem.domain.common.util.UserWalletId
+import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.tap.common.extensions.cardImageData
import com.tangem.tap.features.walletSelector.ui.model.MultiCurrencyUserWalletItem
import com.tangem.tap.features.walletSelector.ui.model.SingleCurrencyUserWalletItem
diff --git a/app/src/main/java/com/tangem/tap/features/walletSelector/ui/model/UserWalletItem.kt b/app/src/main/java/com/tangem/tap/features/walletSelector/ui/model/UserWalletItem.kt
index 7013362085..e5e3033115 100644
--- a/app/src/main/java/com/tangem/tap/features/walletSelector/ui/model/UserWalletItem.kt
+++ b/app/src/main/java/com/tangem/tap/features/walletSelector/ui/model/UserWalletItem.kt
@@ -1,6 +1,6 @@
package com.tangem.tap.features.walletSelector.ui.model
-import com.tangem.domain.common.util.UserWalletId
+import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.tap.features.wallet.redux.utils.UNKNOWN_AMOUNT_SIGN
internal sealed interface UserWalletItem {
diff --git a/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeAction.kt b/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeAction.kt
index a0484fc798..e7ce3e5957 100644
--- a/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeAction.kt
+++ b/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeAction.kt
@@ -15,7 +15,7 @@ internal sealed interface WelcomeAction : Action {
data class Error(val error: TangemError) : WelcomeAction
}
- data class HandleIntentIfNeeded(val intent: Intent?) : WelcomeAction
+ data class SetInitialIntent(val intent: Intent?) : WelcomeAction
object CloseError : WelcomeAction
diff --git a/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeMiddleware.kt b/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeMiddleware.kt
index 9955bf6d6d..8a96417455 100644
--- a/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeMiddleware.kt
+++ b/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeMiddleware.kt
@@ -1,11 +1,12 @@
package com.tangem.tap.features.welcome.redux
-import android.content.Intent
import com.tangem.common.core.TangemSdkError
import com.tangem.common.doOnFailure
import com.tangem.common.doOnResult
import com.tangem.common.doOnSuccess
import com.tangem.common.flatMap
+import com.tangem.core.navigation.AppScreen
+import com.tangem.core.navigation.NavigationAction
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.tap.*
import com.tangem.tap.common.analytics.events.AnalyticsParam
@@ -14,11 +15,10 @@ import com.tangem.tap.common.extensions.dispatchOnMain
import com.tangem.tap.common.extensions.dispatchWithMain
import com.tangem.tap.common.extensions.onUserWalletSelected
import com.tangem.tap.common.redux.AppState
-import com.tangem.tap.common.redux.navigation.AppScreen
-import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.domain.model.builders.UserWalletBuilder
import com.tangem.tap.domain.scanCard.ScanCardProcessor
import com.tangem.tap.domain.userWalletList.unlockIfLockable
+import com.tangem.tap.features.intentHandler.handlers.WalletConnectLinkIntentHandler
import com.tangem.tap.features.signin.redux.SignInAction
import kotlinx.coroutines.launch
import org.rekotlin.Middleware
@@ -39,24 +39,10 @@ internal class WelcomeMiddleware {
private fun handleAction(action: WelcomeAction, state: WelcomeState) {
when (action) {
- is WelcomeAction.ProceedWithBiometrics -> {
- proceedWithBiometrics(state)
- }
- is WelcomeAction.ProceedWithCard -> {
- proceedWithCard(state)
- }
- is WelcomeAction.HandleIntentIfNeeded -> {
- handleInitialIntent(action.intent)
- }
- is WelcomeAction.ClearUserWallets -> {
- disableUserWalletsSaving()
- }
- is WelcomeAction.ProceedWithBiometrics.Error,
- is WelcomeAction.ProceedWithCard.Error,
- is WelcomeAction.ProceedWithBiometrics.Success,
- is WelcomeAction.ProceedWithCard.Success,
- is WelcomeAction.CloseError,
- -> Unit
+ is WelcomeAction.ProceedWithBiometrics -> proceedWithBiometrics(state)
+ is WelcomeAction.ProceedWithCard -> proceedWithCard(state)
+ is WelcomeAction.ClearUserWallets -> disableUserWalletsSaving()
+ else -> Unit
}
}
@@ -85,7 +71,9 @@ internal class WelcomeMiddleware {
store.dispatchOnMain(WelcomeAction.ProceedWithBiometrics.Success)
store.onUserWalletSelected(userWallet = selectedUserWallet)
- intentHandler.handleWalletConnectLink(state.intent)
+ state.intent?.let {
+ WalletConnectLinkIntentHandler().handleIntent(it)
+ }
}
}
@@ -104,20 +92,13 @@ internal class WelcomeMiddleware {
store.dispatchOnMain(WelcomeAction.ProceedWithCard.Success)
store.onUserWalletSelected(userWallet = userWallet)
- intentHandler.handleWalletConnectLink(state.intent)
+ state.intent?.let {
+ WalletConnectLinkIntentHandler().handleIntent(it)
+ }
}
}
}
- private fun handleInitialIntent(intent: Intent?) {
- val isBackgroundScanNotHandled = !intentHandler.handleBackgroundScan(intent, hasSavedUserWallets = true)
- val hasNotIncompletedBackup = !backupService.hasIncompletedBackup
-
- if (isBackgroundScanNotHandled && hasNotIncompletedBackup) {
- store.dispatchOnMain(WelcomeAction.ProceedWithBiometrics)
- }
- }
-
private suspend inline fun scanCardInternal(crossinline onCardScanned: suspend (ScanResponse) -> Unit) {
tangemSdkManager.setAccessCodeRequestPolicy(
useBiometricsForAccessCode = preferencesStorage.shouldSaveAccessCodes,
diff --git a/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeReducer.kt b/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeReducer.kt
index 5f14d1744d..11bfb0ea4a 100644
--- a/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeReducer.kt
+++ b/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeReducer.kt
@@ -14,7 +14,7 @@ internal object WelcomeReducer {
private fun internalReduce(action: WelcomeAction, state: WelcomeState): WelcomeState {
return when (action) {
- is WelcomeAction.HandleIntentIfNeeded -> state.copy(intent = action.intent)
+ is WelcomeAction.SetInitialIntent -> state.copy(intent = action.intent)
is WelcomeAction.ProceedWithBiometrics -> state.copy(isUnlockWithBiometricsInProgress = true)
is WelcomeAction.ProceedWithCard -> state.copy(isUnlockWithCardInProgress = true)
is WelcomeAction.ProceedWithBiometrics.Error -> state.copy(
diff --git a/app/src/main/java/com/tangem/tap/network/payid/PayIdVerifyApi.kt b/app/src/main/java/com/tangem/tap/network/payid/PayIdVerifyApi.kt
deleted file mode 100644
index d9d00a663b..0000000000
--- a/app/src/main/java/com/tangem/tap/network/payid/PayIdVerifyApi.kt
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.tangem.tap.network.payid
-
-import com.squareup.moshi.JsonClass
-import retrofit2.http.GET
-import retrofit2.http.Header
-import retrofit2.http.Path
-
-/**
-[REDACTED_AUTHOR]
- */
-interface PayIdVerifyApi {
- @GET("{user}")
- suspend fun verifyAddress(
- @Path("user") user: String,
- @Header("Accept") acceptNetworkHeader: String,
- @Header("PayID-Version") payIdVersion: String = "1.0",
- ): VerifyPayIdResponse
-}
-
-@JsonClass(generateAdapter = true)
-data class VerifyPayIdResponse(
- val addresses: List = mutableListOf(),
- val payId: String? = null,
-) {
- fun getAddressDetails(): PayIdAddressDetails? = if (addresses.isNotEmpty()) addresses[0].addressDetails else null
-}
-
-@JsonClass(generateAdapter = true)
-data class PayIdAddress(
- var paymentNetwork: String,
- var environment: String,
- var addressDetailsType: String,
- var addressDetails: PayIdAddressDetails,
-)
-
-@JsonClass(generateAdapter = true)
-data class PayIdAddressDetails(
- var address: String,
- var tag: String? = null,
-)
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/network/payid/PayIdVerifyService.kt b/app/src/main/java/com/tangem/tap/network/payid/PayIdVerifyService.kt
deleted file mode 100644
index 05d16f8724..0000000000
--- a/app/src/main/java/com/tangem/tap/network/payid/PayIdVerifyService.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.tangem.tap.network.payid
-
-import com.tangem.common.services.Result
-import com.tangem.common.services.performRequest
-import com.tangem.datasource.api.common.createRetrofitInstance
-
-/**
-[REDACTED_AUTHOR]
- */
-class PayIdVerifyService(
- private val baseUrl: String,
-) {
-
- private val api = createRetrofitInstance(
- baseUrl = baseUrl,
- logEnabled = false,
- ).create(PayIdVerifyApi::class.java)
-
- suspend fun verifyAddress(user: String, network: String): Result {
- return performRequest { api.verifyAddress(user, createNetworkHeader(network)) }
- }
-
- private fun createNetworkHeader(network: String): String = "application/$network-mainnet+json"
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/proxy/AppStateHolder.kt b/app/src/main/java/com/tangem/tap/proxy/AppStateHolder.kt
index 35c2d83718..cf6015d446 100644
--- a/app/src/main/java/com/tangem/tap/proxy/AppStateHolder.kt
+++ b/app/src/main/java/com/tangem/tap/proxy/AppStateHolder.kt
@@ -1,23 +1,28 @@
package com.tangem.tap.proxy
import com.tangem.TangemSdk
+import com.tangem.core.navigation.NavigationAction
+import com.tangem.core.navigation.NavigationStateHolder
import com.tangem.domain.models.scan.CardDTO
import com.tangem.domain.models.scan.ScanResponse
+import com.tangem.domain.wallets.legacy.UserWalletsListManager
+import com.tangem.domain.wallets.legacy.WalletsStateHolder
import com.tangem.tap.common.entities.FiatCurrency
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.domain.TangemSdkManager
import com.tangem.tap.domain.tokens.UserTokensRepository
-import com.tangem.tap.domain.userWalletList.UserWalletsListManager
import com.tangem.tap.domain.walletStores.WalletStoresManager
import com.tangem.tap.features.wallet.redux.WalletState
import org.rekotlin.Store
import javax.inject.Inject
/**
- * Holds objects from old modules, that missing in DI graph
- * Object sets manually to use in new modules and [AppStateHolder] proxies its to DI
+ * Holds objects from old modules, that missing in DI graph.
+ * Object sets manually to use in new modules and [AppStateHolder] proxies its to DI.
*/
-class AppStateHolder @Inject constructor() {
+class AppStateHolder @Inject constructor() : WalletsStateHolder, NavigationStateHolder {
+
+ override var userWalletsListManager: UserWalletsListManager? = null
@Deprecated("Use scan response from selected user wallet")
var scanResponse: ScanResponse? = null
@@ -27,10 +32,13 @@ class AppStateHolder @Inject constructor() {
var tangemSdkManager: TangemSdkManager? = null
var tangemSdk: TangemSdk? = null
var walletStoresManager: WalletStoresManager? = null
- var userWalletsListManager: UserWalletsListManager? = null
var appFiatCurrency: FiatCurrency = FiatCurrency.Default
fun getActualCard(): CardDTO? {
return scanResponse?.card
}
+
+ override fun navigate(action: NavigationAction) {
+ mainStore?.dispatch(action)
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/proxy/DerivationManagerImpl.kt b/app/src/main/java/com/tangem/tap/proxy/DerivationManagerImpl.kt
index c673ac8577..e24eae21c2 100644
--- a/app/src/main/java/com/tangem/tap/proxy/DerivationManagerImpl.kt
+++ b/app/src/main/java/com/tangem/tap/proxy/DerivationManagerImpl.kt
@@ -9,6 +9,7 @@ import com.tangem.common.core.TangemSdkError
import com.tangem.common.extensions.ByteArrayKey
import com.tangem.common.extensions.toMapKey
import com.tangem.crypto.hdWallet.DerivationPath
+import com.tangem.domain.common.BlockchainNetwork
import com.tangem.domain.common.TapWorkarounds.derivationStyle
import com.tangem.domain.common.extensions.fromNetworkId
import com.tangem.domain.common.util.hasDerivation
@@ -23,7 +24,6 @@ import com.tangem.tap.common.extensions.dispatchDebugErrorNotification
import com.tangem.tap.common.extensions.dispatchOnMain
import com.tangem.tap.common.redux.global.GlobalAction
import com.tangem.tap.domain.TapError
-import com.tangem.tap.domain.tokens.models.BlockchainNetwork
import com.tangem.tap.scope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
diff --git a/app/src/main/java/com/tangem/tap/proxy/TransactionManagerImpl.kt b/app/src/main/java/com/tangem/tap/proxy/TransactionManagerImpl.kt
index 7bdd3744b4..e6090dd5f0 100644
--- a/app/src/main/java/com/tangem/tap/proxy/TransactionManagerImpl.kt
+++ b/app/src/main/java/com/tangem/tap/proxy/TransactionManagerImpl.kt
@@ -12,6 +12,7 @@ import com.tangem.blockchain.extensions.isNetworkError
import com.tangem.common.core.TangemSdkError
import com.tangem.common.extensions.hexToBytes
import com.tangem.core.analytics.api.AnalyticsEventHandler
+import com.tangem.domain.common.BlockchainNetwork
import com.tangem.domain.common.extensions.fromNetworkId
import com.tangem.lib.crypto.TransactionManager
import com.tangem.lib.crypto.models.*
@@ -21,7 +22,6 @@ import com.tangem.tap.common.analytics.events.Basic
import com.tangem.tap.common.analytics.events.Basic.TransactionSent.MemoType
import com.tangem.tap.common.redux.global.GlobalAction
import com.tangem.tap.domain.TangemSigner
-import com.tangem.tap.domain.tokens.models.BlockchainNetwork
import com.tangem.tap.tangemSdk
import java.math.BigDecimal
import java.math.BigInteger
diff --git a/app/src/main/java/com/tangem/tap/proxy/UserWalletManagerImpl.kt b/app/src/main/java/com/tangem/tap/proxy/UserWalletManagerImpl.kt
index fba11b855a..1938886ede 100644
--- a/app/src/main/java/com/tangem/tap/proxy/UserWalletManagerImpl.kt
+++ b/app/src/main/java/com/tangem/tap/proxy/UserWalletManagerImpl.kt
@@ -6,6 +6,7 @@ import com.tangem.blockchain.common.Token
import com.tangem.blockchain.common.WalletManager
import com.tangem.common.doOnFailure
import com.tangem.common.extensions.guard
+import com.tangem.domain.common.BlockchainNetwork
import com.tangem.domain.common.extensions.fromNetworkId
import com.tangem.domain.common.extensions.toCoinId
import com.tangem.domain.common.extensions.toNetworkId
@@ -17,7 +18,6 @@ import com.tangem.lib.crypto.models.ProxyAmount
import com.tangem.lib.crypto.models.ProxyFiatCurrency
import com.tangem.tap.common.extensions.dispatchOnMain
import com.tangem.tap.domain.model.builders.UserWalletIdBuilder
-import com.tangem.tap.domain.tokens.models.BlockchainNetwork
import com.tangem.tap.features.wallet.redux.WalletAction
import com.tangem.tap.userWalletsListManager
import com.tangem.tap.walletCurrenciesManager
diff --git a/app/src/main/java/com/tangem/tap/proxy/di/ProxyModule.kt b/app/src/main/java/com/tangem/tap/proxy/di/ProxyModule.kt
index 1189c0895d..371f1e21bf 100644
--- a/app/src/main/java/com/tangem/tap/proxy/di/ProxyModule.kt
+++ b/app/src/main/java/com/tangem/tap/proxy/di/ProxyModule.kt
@@ -1,6 +1,8 @@
package com.tangem.tap.proxy.di
+import androidx.compose.ui.text.intl.Locale
import com.tangem.core.analytics.api.AnalyticsEventHandler
+import com.tangem.feature.learn2earn.domain.api.Learn2earnDependencyProvider
import com.tangem.lib.crypto.DerivationManager
import com.tangem.lib.crypto.TransactionManager
import com.tangem.lib.crypto.UserWalletManager
@@ -48,4 +50,20 @@ class ProxyModule {
appStateHolder = appStateHolder,
)
}
+
+ // regions FeatureConsumers
+ @Provides
+ @Singleton
+ fun provideLear2earnDependencies(appStateHolder: AppStateHolder): Learn2earnDependencyProvider {
+ return object : Learn2earnDependencyProvider {
+ override fun getUserCountryCodeProvider(): () -> String = {
+ appStateHolder.mainStore?.state?.globalState?.userCountryCode ?: Locale.current.language
+ }
+
+ override fun getWebViewAuthCredentialsProvider(): () -> String? = {
+ appStateHolder.mainStore?.state?.globalState?.configManager?.config?.tangemComAuthorization
+ }
+ }
+ }
+ // endregion FeatureConsumers
}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphAction.kt b/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphAction.kt
index 5fab5032f5..e83ed33f3a 100644
--- a/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphAction.kt
+++ b/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphAction.kt
@@ -2,6 +2,7 @@ package com.tangem.tap.proxy.redux
import com.tangem.domain.card.ScanCardUseCase
import com.tangem.features.tester.api.TesterRouter
+import com.tangem.features.tokendetails.navigation.TokenDetailsRouter
import com.tangem.features.wallet.navigation.WalletRouter
import com.tangem.tap.domain.walletconnect2.domain.WalletConnectInteractor
import org.rekotlin.Action
@@ -13,5 +14,6 @@ sealed interface DaggerGraphAction : Action {
val scanCardUseCase: ScanCardUseCase,
val walletRouter: WalletRouter,
val walletConnectInteractor: WalletConnectInteractor,
+ val tokenDetailsRouter: TokenDetailsRouter,
) : DaggerGraphAction
}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphReducer.kt b/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphReducer.kt
index bdc38a631c..bdd590be4d 100644
--- a/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphReducer.kt
+++ b/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphReducer.kt
@@ -17,6 +17,7 @@ object DaggerGraphReducer {
scanCardUseCase = action.scanCardUseCase,
walletRouter = action.walletRouter,
walletConnectInteractor = action.walletConnectInteractor,
+ tokenDetailsRouter = action.tokenDetailsRouter,
)
}
}
diff --git a/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphState.kt b/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphState.kt
index a741e4dfd4..84409d4e36 100644
--- a/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphState.kt
+++ b/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphState.kt
@@ -4,6 +4,8 @@ import com.tangem.datasource.asset.AssetReader
import com.tangem.datasource.connection.NetworkConnectionManager
import com.tangem.domain.card.ScanCardUseCase
import com.tangem.features.tester.api.TesterRouter
+import com.tangem.features.tokendetails.featuretoggles.TokenDetailsFeatureToggles
+import com.tangem.features.tokendetails.navigation.TokenDetailsRouter
import com.tangem.features.wallet.featuretoggles.WalletFeatureToggles
import com.tangem.features.wallet.navigation.WalletRouter
import com.tangem.tap.domain.walletconnect2.domain.WalletConnectInteractor
@@ -23,6 +25,8 @@ data class DaggerGraphState(
val walletConnectRepository: WalletConnectRepository? = null,
val walletConnectSessionsRepository: WalletConnectSessionsRepository? = null,
val walletConnectInteractor: WalletConnectInteractor? = null,
+ val tokenDetailsFeatureToggles: TokenDetailsFeatureToggles? = null,
+ val tokenDetailsRouter: TokenDetailsRouter? = null,
) : StateType {
inline fun get(getDependency: DaggerGraphState.() -> T?): T {
diff --git a/app/src/main/res/drawable/ic_azero_no_color.xml b/app/src/main/res/drawable/ic_azero_no_color.xml
new file mode 100644
index 0000000000..da712895b3
--- /dev/null
+++ b/app/src/main/res/drawable/ic_azero_no_color.xml
@@ -0,0 +1,12 @@
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_telos_no_color.xml b/app/src/main/res/drawable/ic_telos_no_color.xml
new file mode 100644
index 0000000000..01aca1d2b2
--- /dev/null
+++ b/app/src/main/res/drawable/ic_telos_no_color.xml
@@ -0,0 +1,15 @@
+
+
+
+
diff --git a/app/src/main/res/layout/dialog_wallet_trade.xml b/app/src/main/res/layout/dialog_wallet_trade.xml
index b2e6a5e45b..dea867e05a 100644
--- a/app/src/main/res/layout/dialog_wallet_trade.xml
+++ b/app/src/main/res/layout/dialog_wallet_trade.xml
@@ -23,7 +23,7 @@
android:focusable="true"
android:gravity="center_vertical"
android:padding="16dp"
- android:text="@string/wallet_button_buy"
+ android:text="@string/common_buy"
android:textColor="@color/darkGray3"
android:textSize="14sp"
android:textStyle="bold"
@@ -38,7 +38,7 @@
android:focusable="true"
android:gravity="center_vertical"
android:padding="16dp"
- android:text="@string/wallet_button_sell"
+ android:text="@string/common_sell"
android:textColor="@color/darkGray3"
android:textSize="14sp"
android:textStyle="bold"
diff --git a/app/src/main/res/layout/fragment_send.xml b/app/src/main/res/layout/fragment_send.xml
index fe0eebf2a3..4035f923e2 100644
--- a/app/src/main/res/layout/fragment_send.xml
+++ b/app/src/main/res/layout/fragment_send.xml
@@ -22,7 +22,7 @@
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:navigationIcon="@drawable/ic_baseline_arrow_back_24"
- app:title="@string/send_title" />
+ app:title="@string/common_send" />
@@ -39,8 +39,8 @@
android:orientation="vertical">
@@ -115,7 +115,7 @@
style="@style/TapPrimaryIconButton"
android:layout_width="match_parent"
android:fontFamily="@font/saira_semi_condensed_regular"
- android:text="@string/send_title"
+ android:text="@string/common_send"
app:icon="@drawable/ic_arrow_right" />
+
+
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/layout/layout_send_address_payid.xml b/app/src/main/res/layout/layout_send_address.xml
similarity index 84%
rename from app/src/main/res/layout/layout_send_address_payid.xml
rename to app/src/main/res/layout/layout_send_address.xml
index 1bf69a649f..c6dd2873c8 100644
--- a/app/src/main/res/layout/layout_send_address_payid.xml
+++ b/app/src/main/res/layout/layout_send_address.xml
@@ -18,10 +18,9 @@
app:layout_constraintTop_toTopOf="parent">
+ app:layout_constraintTop_toTopOf="@+id/tilAddress">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ app:layout_constraintTop_toBottomOf="@+id/tilAddress">
@@ -51,7 +51,7 @@
style="@style/TapPrimaryIconButton"
android:layout_width="0dp"
android:layout_weight="1"
- android:text="@string/wallet_button_send"
+ android:text="@string/common_send"
app:icon="@drawable/ic_send" />
diff --git a/app/src/main/res/values-v24/bool.xml b/app/src/main/res/values-v24/bool.xml
index 093ecf3bc6..d5677354f0 100644
--- a/app/src/main/res/values-v24/bool.xml
+++ b/app/src/main/res/values-v24/bool.xml
@@ -1,5 +1,5 @@
- false
+ true
diff --git a/app/src/tangemAccess/java/com/tangem/Test2.java b/app/src/tangemAccess/java/com/tangem/Test2.java
deleted file mode 100644
index c4c336af47..0000000000
--- a/app/src/tangemAccess/java/com/tangem/Test2.java
+++ /dev/null
@@ -1,4 +0,0 @@
-package com.tangem;
-
-public class Test2 {
-}
diff --git a/app/src/tangemAccess/java/com/tangem/ui/ConfirmTransactionFragment.kt b/app/src/tangemAccess/java/com/tangem/ui/ConfirmTransactionFragment.kt
deleted file mode 100644
index f934c827fc..0000000000
--- a/app/src/tangemAccess/java/com/tangem/ui/ConfirmTransactionFragment.kt
+++ /dev/null
@@ -1,305 +0,0 @@
-package com.tangem.ui
-
-import android.app.Activity
-import android.content.SharedPreferences
-import android.nfc.NfcAdapter
-import android.nfc.Tag
-import android.os.Build
-import android.os.Bundle
-import android.preference.PreferenceManager
-import android.text.Editable
-import android.text.Html
-import android.text.TextWatcher
-import android.util.Log
-import android.view.View
-import android.widget.Toast
-import androidx.activity.OnBackPressedCallback
-import androidx.core.os.bundleOf
-import com.tangem.Constant
-import com.tangem.data.Blockchain
-import com.tangem.tangem_card.data.TangemCard
-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.loadFromBundle
-import com.tangem.ui.activity.MainActivity
-import com.tangem.ui.fragment.BaseFragment
-import com.tangem.ui.fragment.pin.PinRequestFragment
-import com.tangem.ui.navigation.NavigationResultListener
-import com.tangem.util.UtilHelper
-import com.tangem.wallet.CoinEngine
-import com.tangem.wallet.CoinEngineFactory
-import com.tangem.wallet.R
-import com.tangem.wallet.TangemContext
-import kotlinx.android.synthetic.tangemAccess.fragment_confirm_transaction.*
-import java.io.IOException
-import java.util.*
-
-class ConfirmTransactionFragment : BaseFragment(), NavigationResultListener, NfcAdapter.ReaderCallback {
-
- override val layoutId = R.layout.fragment_confirm_transaction
-
- private lateinit var sp: SharedPreferences
- private lateinit var ctx: TangemContext
- private lateinit var amount: CoinEngine.Amount
-
- private var isIncludeFee: Boolean = true
- private var requestPIN2Count = 0
- private var nodeCheck = true
- private var dtVerified: Date? = null
-
- private var blockchainCallbacks: CoinEngine.BlockchainRequestsCallbacks? = null
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
-
- sp = PreferenceManager.getDefaultSharedPreferences(context)
- ctx = TangemContext.loadFromBundle(requireContext(), arguments)
-
- val callback = object : OnBackPressedCallback(true) {
- override fun handleOnBackPressed() {
- navigateUp()
- }
- }
- requireActivity().onBackPressedDispatcher.addCallback(this, callback)
- }
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
-
- val engine = CoinEngineFactory.create(ctx)
-
- @Suppress("DEPRECATION") val html = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
- Html.fromHtml(engine!!.balanceHTML, Html.FROM_HTML_MODE_LEGACY)
- else
- Html.fromHtml(engine!!.balanceHTML)
- tvBalance.text = html
-
- isIncludeFee = arguments?.getBoolean(Constant.EXTRA_FEE_INCLUDED, true) ?: true
-
- if (isIncludeFee)
- tvIncFee.setText(R.string.confirm_transaction_including_fee)
- else
- tvIncFee.setText(R.string.confirm_transaction_not_including_fee)
-
- amount = CoinEngine.Amount(arguments?.getString(Constant.EXTRA_AMOUNT) ?: "0",
- arguments?.getString(Constant.EXTRA_AMOUNT_CURRENCY) ?: "")
-
- if (engine.allowSelectFeeInclusion())
- tvIncFee.visibility = View.VISIBLE
- else
- tvIncFee.visibility = View.INVISIBLE
-
- if (ctx.card.blockchainID == Blockchain.Token.id) {
- // for Blockchain.Token limit decimals
- etAmount.setText(amount.toValueString(ctx.card.tokensDecimal))
- } else {
- // for others
- etAmount.setText(amount.toValueString())
- }
-
- tvCurrency.text = engine.balanceCurrency
- tvCurrency2.text = engine.feeCurrency
- tvCardID.text = ctx.card.cidDescription
- etWallet.setText(arguments?.getString(Constant.EXTRA_TARGET_ADDRESS))
-
- btnSend.visibility = View.INVISIBLE
-
- if (!engine.allowSelectFeeLevel()) {
- rgFee.visibility = View.INVISIBLE
- }
-
- etFee.isEnabled = sp.getBoolean(getString(R.string.pref_manual_editing_fee), false)
-
- // set listeners
- rgFee.setOnCheckedChangeListener { _, checkedId -> doSetFee(checkedId) }
- etFee.addTextChangedListener(object : TextWatcher {
- override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
-
- }
-
- override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
- try {
- val eqFee = engine.evaluateFeeEquivalent(etFee!!.text.toString())
- tvFeeEquivalent.text = eqFee
-
- if (!ctx.coinData!!.amountEquivalentDescriptionAvailable) {
- tvFeeEquivalent.error = getString(R.string.confirm_transaction_error_service_unavailable)
- tvCurrency2.visibility = View.GONE
- tvFeeEquivalent.visibility = View.GONE
- } else
- tvFeeEquivalent.error = null
-
- if (sp.getBoolean(getString(R.string.pref_manual_editing_fee), false))
- (activity as MainActivity).toastHelper
- .showSingleToast(context, getString(R.string.confirm_transaction_warning_risk_delaying))
-
- } catch (e: Exception) {
- e.printStackTrace()
- tvFeeEquivalent.text = ""
- }
- }
-
- override fun afterTextChanged(s: Editable) {
-
- }
- })
- btnSend.setOnClickListener {
- if (UtilHelper.isOnline(requireContext())) {
- val calendar = Calendar.getInstance()
- calendar.add(Calendar.MINUTE, -1)
-
- if (dtVerified == null || dtVerified!!.before(calendar.time)) {
- finishWithError(Activity.RESULT_CANCELED, getString(R.string.confirm_transaction_error_data_is_outdated))
- return@setOnClickListener
- }
-
- val engineCoin = CoinEngineFactory.create(ctx)
-
- if (engineCoin!!.isNeedCheckNode && !nodeCheck) {
- Toast.makeText(context, getString(R.string.confirm_transaction_error_cannot_reach_node), Toast.LENGTH_LONG).show()
- return@setOnClickListener
- }
-
- val txFee = engineCoin.convertToAmount(etFee.text.toString(), tvCurrency2.text.toString())
- val txAmount = engineCoin.convertToAmount(etAmount.text.toString(), tvCurrency.text.toString())
-
- if (!engineCoin.hasBalanceInfo()) {
- finishWithError(Activity.RESULT_CANCELED, getString(R.string.confirm_transaction_error_cannot_check_balance))
- return@setOnClickListener
-
- } else if (!engineCoin.isBalanceNotZero) {
- finishWithError(Activity.RESULT_CANCELED, getString(R.string.general_wallet_empty))
- return@setOnClickListener
-
- } else if (!engineCoin.isExtractPossible) {
- finishWithError(Activity.RESULT_CANCELED, getString(R.string.confirm_transaction_error_incoming_transaction_unconfirmed))
- return@setOnClickListener
- }
-
- if (!engineCoin.checkNewTransactionAmountAndFee(txAmount, txFee, isIncludeFee)) {
- finishWithError(Activity.RESULT_CANCELED, getString(R.string.prepare_transaction_error_not_enough_funds))
- return@setOnClickListener
- }
-
- requestPIN2Count = 0
- val data = Bundle()
- data.putString(Constant.EXTRA_MODE, PinRequestFragment.Mode.RequestPIN2.toString())
- ctx.saveToBundle(data)
- data.putBoolean(Constant.EXTRA_FEE_INCLUDED, isIncludeFee)
- navigateForResult(Constant.REQUEST_CODE_REQUEST_PIN2_, R.id.action_confirmTransactionFragment_to_pinRequestFragment, data)
- } else
- Toast.makeText(context, getString(R.string.general_error_no_connection), Toast.LENGTH_SHORT).show()
- }
-
- progressBar.visibility = View.VISIBLE
-
- if (!navigatedBack) requestFee()
- }
-
- private fun requestFee() {
- val coinEngine = CoinEngineFactory.create(ctx)
- coinEngine!!.requestFee(
- object : CoinEngine.BlockchainRequestsCallbacks {
- override fun onComplete(success: Boolean) {
- if (success) {
- progressBar?.visibility = View.INVISIBLE
- dtVerified = Date()
- doSetFee(rgFee?.checkedRadioButtonId ?: R.id.rbNormalFee)
- } else {
- finishWithError(Activity.RESULT_CANCELED, ctx.error)
- }
- }
-
- override fun onProgress() {
- }
-
- override fun allowAdvance(): Boolean {
- return UtilHelper.isOnline(requireContext())
- }
- },
- etWallet.text.toString(),
- amount)
- }
-
- override fun onNavigationResult(requestCode: String, resultCode: Int, data: Bundle?) {
- Log.d("LIFECYCLE", "NavigationResult assessed ${this::class.java.simpleName}")
- if (requestCode == Constant.REQUEST_CODE_SIGN_TRANSACTION) {
- if (data != null) {
- if (data.containsKey(EXTRA_TANGEM_CARD_UID) && data.containsKey(EXTRA_TANGEM_CARD)) {
- val updatedCard = TangemCard(data.getString(EXTRA_TANGEM_CARD_UID))
- updatedCard.loadFromBundle(data.getBundle(EXTRA_TANGEM_CARD))
- ctx.card = updatedCard
- }
- }
- if (resultCode == Constant.RESULT_INVALID_PIN_ && requestPIN2Count < 2) {
- requestPIN2Count++
- val bundle = Bundle()
- bundle.putString(Constant.EXTRA_MODE, PinRequestFragment.Mode.RequestPIN2.toString())
- ctx.saveToBundle(bundle)
- bundle.putBoolean(Constant.EXTRA_FEE_INCLUDED, isIncludeFee)
- navigateForResult(Constant.REQUEST_CODE_REQUEST_PIN2_,
- R.id.action_confirmTransactionFragment_to_pinRequestFragment,
- bundle)
- return
- }
- navigateBackWithResult(resultCode, data)
- } else if (requestCode == Constant.REQUEST_CODE_REQUEST_PIN2_) {
- if (resultCode == Activity.RESULT_OK) {
- val bundle = Bundle()
- ctx.saveToBundle(bundle)
- bundle.putString(Constant.EXTRA_TARGET_ADDRESS, etWallet!!.text.toString())
- bundle.putString(Constant.EXTRA_AMOUNT, etAmount.text.toString())
- bundle.putString(Constant.EXTRA_AMOUNT_CURRENCY, tvCurrency.text.toString())
- bundle.putString(Constant.EXTRA_FEE, etFee.text.toString())
- bundle.putString(Constant.EXTRA_FEE_CURRENCY, tvCurrency2.text.toString())
- bundle.putBoolean(Constant.EXTRA_FEE_INCLUDED, isIncludeFee)
- navigateForResult(Constant.REQUEST_CODE_SIGN_TRANSACTION,
- R.id.action_confirmTransactionFragment_to_signTransactionFragment,
- bundle)
- } else
- Toast.makeText(context, R.string.confirm_transaction_error_pin_2_is_required, Toast.LENGTH_LONG).show()
- }
- }
-
- override fun onTagDiscovered(tag: Tag) {
- try {
- (activity as MainActivity).nfcManager.ignoreTag(tag)
- } catch (e: IOException) {
- e.printStackTrace()
- }
- }
-
- private fun doSetFee(checkedRadioButtonId: Int) {
- var txtFee = ""
- when (checkedRadioButtonId) {
- R.id.rbMinimalFee ->
- if (ctx.coinData.minFee != null) {
- txtFee = ctx.coinData.minFee!!.toValueString()
- btnSend?.visibility = View.VISIBLE
- } else
- btnSend?.visibility = View.INVISIBLE
-
- R.id.rbNormalFee ->
- if (ctx.coinData.normalFee != null) {
- txtFee = ctx.coinData.normalFee!!.toValueString()
- btnSend?.visibility = View.VISIBLE
- } else
- btnSend?.visibility = View.INVISIBLE
-
- R.id.rbMaximumFee ->
- if (ctx.coinData.maxFee != null) {
- txtFee = ctx.coinData.maxFee!!.toValueString()
- btnSend?.visibility = View.VISIBLE
- } else
- btnSend?.visibility = View.INVISIBLE
- }
- etFee?.setText(txtFee.replace(',', '.'))
- }
-
- private fun finishWithError(errorCode: Int, message: String) {
- navigateBackWithResult(
- errorCode,
- bundleOf(Constant.EXTRA_MESSAGE to message),
- R.id.loadedWalletFragment)
- }
-}
\ No newline at end of file
diff --git a/app/src/tangemAccess/java/com/tangem/ui/PrepareTransactionFragment.kt b/app/src/tangemAccess/java/com/tangem/ui/PrepareTransactionFragment.kt
deleted file mode 100644
index 387f992bb6..0000000000
--- a/app/src/tangemAccess/java/com/tangem/ui/PrepareTransactionFragment.kt
+++ /dev/null
@@ -1,182 +0,0 @@
-package com.tangem.ui
-
-import android.app.Activity
-import android.content.Context
-import android.nfc.NfcAdapter
-import android.nfc.Tag
-import android.os.Build
-import android.os.Bundle
-import android.text.Html
-import android.view.View
-import android.view.inputmethod.EditorInfo
-import android.view.inputmethod.InputMethodManager
-import android.widget.Toast
-import com.tangem.Constant
-import com.tangem.data.isPayIdSupported
-import com.tangem.ui.activity.MainActivity
-import com.tangem.ui.fragment.BaseFragment
-import com.tangem.ui.fragment.qr.CameraPermissionManager
-import com.tangem.ui.navigation.NavigationResultListener
-import com.tangem.util.UtilHelper
-import com.tangem.util.extensions.isStart2CoinCard
-import com.tangem.wallet.CoinEngineFactory
-import com.tangem.wallet.R
-import com.tangem.wallet.TangemContext
-import kotlinx.android.synthetic.tangemAccess.fragment_prepare_transaction.*
-import java.io.IOException
-
-class PrepareTransactionFragment : BaseFragment(), NavigationResultListener, NfcAdapter.ReaderCallback {
- companion object {
- val TAG: String = PrepareTransactionFragment::class.java.simpleName
- }
-
- override val layoutId = R.layout.fragment_prepare_transaction
-
- private val ctx: TangemContext by lazy { TangemContext.loadFromBundle(context, arguments) }
- private val cameraPermissionManager: CameraPermissionManager by lazy { CameraPermissionManager(this) }
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
-
- tvCardID.text = ctx.card?.cidDescription
- val engine = CoinEngineFactory.create(ctx)
-
- @Suppress("DEPRECATION") val html = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
- Html.fromHtml(engine!!.balanceHTML, Html.FROM_HTML_MODE_LEGACY)
- else
- Html.fromHtml(engine!!.balanceHTML)
- tvBalance.text = html
-
- if (ctx.blockchain.isPayIdSupported() && !ctx.card.isStart2CoinCard()) {
- etWallet.hint = getString(R.string.prepare_transaction_hint_address_or_pay_id)
- }
-
- if (!engine.allowSelectFeeInclusion()) {
- rgIncFee.visibility = View.INVISIBLE
- } else {
- rgIncFee.visibility = View.VISIBLE
- }
-
- 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())
-
- // limit number of symbols after comma
- etAmount.filters = engine.amountInputFilters
-
- // set listeners
- etAmount.setOnEditorActionListener { lv, actionId, _ ->
- if (actionId == EditorInfo.IME_ACTION_DONE) {
- val imm = lv.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
- imm.hideSoftInputFromWindow(lv.windowToken, 0)
- lv.clearFocus()
- true
- } else {
- false
- }
- }
-
- btnVerify.setOnClickListener {
- if (!UtilHelper.isOnline(requireContext())) {
- Toast.makeText(context, R.string.general_error_no_connection, Toast.LENGTH_LONG).show()
- return@setOnClickListener
- }
-
- val engine1 = CoinEngineFactory.create(ctx)
- val strAmount: String = etAmount.text.toString().replace(",", ".")
- val amount = engine1!!.convertToAmount(etAmount.text.toString(), tvCurrency.text.toString())
-
- try {
- if (!engine.checkNewTransactionAmount(amount))
- etAmount.error = getString(R.string.prepare_transaction_error_not_enough_funds)
- else
- etAmount.error = null
- } catch (e: Exception) {
- etAmount.error = getString(R.string.prepare_transaction_error_unknown_amount_format)
- }
-
- // check wallet address
- if (!engine1.validateAddress(etWallet.text.toString())) {
- etWallet.error = getString(R.string.prepare_transaction_error_incorrect_destination)
- return@setOnClickListener
- } else
- etWallet.error = null
-
- if (etWallet.text.toString() == ctx.coinData!!.wallet) {
- etWallet.error = getString(R.string.prepare_transaction_error_same_address)
- return@setOnClickListener
- }
-
- if (!etAmount.error.isNullOrEmpty() || !etWallet.error.isNullOrEmpty()) {
- return@setOnClickListener
- }
-
- val data = Bundle()
- ctx.saveToBundle(data)
- data.putString(Constant.EXTRA_TARGET_ADDRESS, etWallet!!.text.toString())
- data.putBoolean(Constant.EXTRA_FEE_INCLUDED, (rgIncFee!!.checkedRadioButtonId == R.id.rbFeeIn))
- data.putString(Constant.EXTRA_AMOUNT, strAmount)
- data.putString(Constant.EXTRA_AMOUNT_CURRENCY, tvCurrency.text.toString())
- navigateForResult(
- Constant.REQUEST_CODE_SEND_TRANSACTION__,
- R.id.action_prepareTransactionFragment_to_confirmTransactionFragment,
- data)
- }
-
- ivCamera.setOnClickListener {
- if (cameraPermissionManager.isPermissionGranted()) {
- navigateForResult(Constant.REQUEST_CODE_SCAN_QR, R.id.action_prepareTransactionFragment_to_qrScanFragment)
- } else {
- cameraPermissionManager.requirePermission()
- }
- }
- }
-
- override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) {
- super.onRequestPermissionsResult(requestCode, permissions, grantResults)
- cameraPermissionManager.handleRequestPermissionResult(requestCode, grantResults) {
- navigateForResult(Constant.REQUEST_CODE_SCAN_QR, R.id.action_prepareTransactionFragment_to_qrScanFragment)
- }
- }
-
- override fun onNavigationResult(requestCode: String, resultCode: Int, data: Bundle?) {
- if (requestCode == Constant.REQUEST_CODE_SCAN_QR && resultCode == Activity.RESULT_OK && data != null && data.containsKey("QRCode")) {
- val code = data.getString("QRCode")
- val schemeSplit = code!!.split(":")
- when (schemeSplit.size) {
- 2 -> {
- if (schemeSplit[0] == ctx.blockchain.uriScheme) {
- etWallet?.setText(schemeSplit[1])
- } else {
- etWallet?.setText(code)
- }
- }
- else -> {
- etWallet?.setText(code)
- }
- }
- } else if (requestCode == Constant.REQUEST_CODE_SEND_TRANSACTION__) {
- navigateBackWithResult(resultCode, data)
- }
- }
-
- override fun onTagDiscovered(tag: Tag) {
- try {
- (activity as MainActivity).nfcManager.ignoreTag(tag)
- } catch (e: IOException) {
- e.printStackTrace()
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/tangemAccess/java/com/tangem/ui/SignTransactionFragment.kt b/app/src/tangemAccess/java/com/tangem/ui/SignTransactionFragment.kt
deleted file mode 100644
index fdcdc64a72..0000000000
--- a/app/src/tangemAccess/java/com/tangem/ui/SignTransactionFragment.kt
+++ /dev/null
@@ -1,312 +0,0 @@
-package com.tangem.ui
-
-import android.app.Activity
-import android.content.res.ColorStateList
-import android.graphics.Color
-import android.media.MediaPlayer
-import android.nfc.NfcAdapter
-import android.nfc.Tag
-import android.nfc.tech.IsoDep
-import android.os.Bundle
-import android.view.View
-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
-import com.tangem.tangem_card.tasks.SignTask
-import com.tangem.tangem_card.util.Util
-import com.tangem.tangem_sdk.android.nfc.NfcDeviceAntennaLocation
-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.activity.MainActivity
-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
-import com.tangem.wallet.R
-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.*
-
-
-class SignTransactionFragment : BaseFragment(), NavigationResultListener,
- NfcAdapter.ReaderCallback, CardProtocol.Notifications {
-
- companion object {
- val TAG: String = SignTransactionFragment::class.java.simpleName
- }
-
- override val layoutId = R.layout.fragment_sign_transaction
-
- private lateinit var ctx: TangemContext
- private lateinit var mpFinishSignSound: MediaPlayer
-
- private lateinit var nfcDeviceAntenna: NfcDeviceAntennaLocation
-
- private var signTransactionTask: SignTask? = null
-
- private lateinit var amount: CoinEngine.Amount
- private lateinit var fee: CoinEngine.Amount
- private var isIncludeFee = true
- private var outAddressStr: String? = null
- private var lastReadSuccess = true
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- ctx = TangemContext.loadFromBundle(context, arguments)
-
- val callback = object : OnBackPressedCallback(true) {
- override fun handleOnBackPressed() {
- navigateBackWithResult(Activity.RESULT_CANCELED)
- }
- }
- requireActivity().onBackPressedDispatcher.addCallback(this, callback)
- }
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
-
- mpFinishSignSound = MediaPlayer.create(context, R.raw.scan_card_sound)
-
- // init NFC Antenna
- nfcDeviceAntenna = NfcDeviceAntennaLocation(requireContext(), ivHandCardHorizontal, ivHandCardVertical, llHand, llNfc)
- nfcDeviceAntenna.init()
-
- amount = CoinEngine.Amount(arguments?.getString(Constant.EXTRA_AMOUNT), arguments?.getString(Constant.EXTRA_AMOUNT_CURRENCY))
- fee = CoinEngine.Amount(arguments?.getString(Constant.EXTRA_FEE), arguments?.getString(Constant.EXTRA_FEE_CURRENCY))
- isIncludeFee = arguments?.getBoolean(Constant.EXTRA_FEE_INCLUDED, true) ?: true
- outAddressStr = arguments?.getString(Constant.EXTRA_TARGET_ADDRESS)
-
- 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() {
- signTransactionTask?.cancel(true)
- super.onPause()
- }
-
- override fun onStop() {
- signTransactionTask?.cancel(true)
- super.onStop()
- }
-
- override fun onNavigationResult(requestCode: String, resultCode: Int, data: Bundle?) {
- if (requestCode == Constant.REQUEST_CODE_SEND_TRANSACTION_) {
- navigateBackWithResult(resultCode, data)
- }
- }
-
- override fun onTagDiscovered(tag: Tag) {
- try {
- // get IsoDep handle and run cardReader thread
- val isoDep = IsoDep.get(tag)
- val uid = tag.id
- val sUID = Util.byteArrayToHexString(uid)
-
- if (sUID == ctx.card.uid) {
- if (lastReadSuccess)
- isoDep.timeout = ctx.card.pauseBeforePIN2 + 5000
- else
- isoDep.timeout = ctx.card.pauseBeforePIN2 + 65000
-
- val coinEngine = CoinEngineFactory.create(ctx)
- coinEngine?.setOnNeedSendTransaction { tx ->
- if (tx != null) {
- val data = Bundle()
- ctx.saveToBundle(data)
- data.putByteArray(Constant.EXTRA_TX, tx)
- navigateForResult(
- Constant.REQUEST_CODE_SEND_TRANSACTION_,
- R.id.action_signTransactionFragment_to_sendTransactionFragment,
- data)
- }
- }
- val transactionToSign = coinEngine?.constructTransaction(amount, fee, isIncludeFee, outAddressStr)
-
- signTransactionTask = SignTask(ctx.card, NfcReader((activity as MainActivity).nfcManager, isoDep),
- App.localStorage, App.pinStorage, this, transactionToSign)
- signTransactionTask?.start()
- } else
- (activity as MainActivity).nfcManager.ignoreTag(isoDep.tag)
-
- } catch (e: CardProtocol.TangemException_WrongAmount) {
- try {
- val data = Bundle()
- data.putString(Constant.EXTRA_MESSAGE, getString(R.string.send_transaction_error_wrong_amount))
- data.putString(EXTRA_TANGEM_CARD_UID, ctx.card.uid)
- data.putBundle(EXTRA_TANGEM_CARD, ctx.card.asBundle)
- navigateBackWithResult(Activity.RESULT_CANCELED, data)
- } catch (e: Exception) {
- e.printStackTrace()
- }
- } catch(e: IllegalArgumentException) {
- val data = Bundle()
- data.putString(Constant.EXTRA_MESSAGE, e.message)
- navigateBackWithResult(Activity.RESULT_CANCELED, data, R.id.loadedWalletFragment)
- } catch (e: Exception) {
- e.printStackTrace()
- }
- }
-
- override fun onReadStart(cardProtocol: CardProtocol) {
- rlProgressBar?.post { rlProgressBar.visibility = View.VISIBLE }
-
- progressBar?.post {
- progressBar?.visibility = View.VISIBLE
- progressBar?.progress = 5
- }
- }
-
- override fun onReadProgress(protocol: CardProtocol, progress: Int) {
- progressBar?.post { progressBar?.progress = progress }
- }
-
- override fun onReadFinish(cardProtocol: CardProtocol?) {
- 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 {
- progressBar?.progress = 100
- progressBar?.progressTintList = ColorStateList.valueOf(Color.GREEN)
- }
-
- mpFinishSignSound.start()
- } else {
- lastReadSuccess = false
- FirebaseCrashlytics.getInstance().recordException(cardProtocol.error)
- if (cardProtocol.error.javaClass == CardProtocol.TangemException_InvalidPIN::class.java) {
- progressBar?.post {
- progressBar?.progress = 100
- progressBar?.progressTintList = ColorStateList.valueOf(Color.RED)
- }
- progressBar?.postDelayed({
- try {
- progressBar?.progress = 0
- progressBar?.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
- progressBar?.visibility = View.INVISIBLE
- val data = Bundle()
- data.putString(Constant.EXTRA_MESSAGE, getString(R.string.send_transaction_error_cannot_sign))
- data.putString(EXTRA_TANGEM_CARD_UID, cardProtocol.card.uid)
- data.putBundle(EXTRA_TANGEM_CARD, cardProtocol.card.asBundle)
- navigateBackWithResult(Constant.RESULT_INVALID_PIN_, data)
- } catch (e: Exception) {
- e.printStackTrace()
- }
- }, 500)
- } else {
- if (cardProtocol.error is CardProtocol.TangemException_WrongAmount) {
- try {
- val data = Bundle()
- data.putString(Constant.EXTRA_MESSAGE, getString(R.string.send_transaction_error_wrong_amount))
- data.putString(EXTRA_TANGEM_CARD_UID, cardProtocol.card.uid)
- data.putBundle(EXTRA_TANGEM_CARD, cardProtocol.card.asBundle)
- navigateBackWithResult(Activity.RESULT_CANCELED, data)
- } catch (e: Exception) {
- e.printStackTrace()
- }
- }
- progressBar?.post {
- if (cardProtocol.error is CardProtocol.TangemException_ExtendedLengthNotSupported) {
- if (!NoExtendedLengthSupportDialog.allReadyShowed) {
- NoExtendedLengthSupportDialog.message = getText(R.string.dialog_the_nfc_adapter_length_apdu).toString() + "\n" + getText(R.string.dialog_the_nfc_adapter_length_apdu_advice).toString()
- NoExtendedLengthSupportDialog().show(requireFragmentManager(), NoExtendedLengthSupportDialog.TAG)
- }
- } else {
- (activity as? MainActivity)?.toastHelper?.showSingleToast(
- context, getString(R.string.general_notification_scan_again)
- )
- }
- progressBar?.progress = 100
- progressBar?.progressTintList = ColorStateList.valueOf(Color.RED)
- }
- }
- }
- }
-
- rlProgressBar?.postDelayed({
- try {
- rlProgressBar?.visibility = View.GONE
- } catch (e: Exception) {
- e.printStackTrace()
- }
- }, 500)
-
- progressBar?.postDelayed({
- try {
- progressBar?.progress = 0
- progressBar?.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
- progressBar?.visibility = View.INVISIBLE
- } catch (e: Exception) {
- e.printStackTrace()
- }
- }, 500)
- }
-
- override fun onReadCancel() {
- signTransactionTask = null
-
- progressBar?.postDelayed({
- try {
- progressBar?.progress = 0
- progressBar?.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
- progressBar?.visibility = View.INVISIBLE
- } catch (e: Exception) {
- e.printStackTrace()
- }
- }, 500)
- }
-
-// private val waitSecurityDelayDialogNew = WaitSecurityDelayDialogNew()
-
- override fun onReadBeforeRequest(timeout: Int) {
- LOG.i(TAG, "onReadBeforeRequest timeout $timeout")
- activity?.let { WaitSecurityDelayDialog.onReadBeforeRequest(it, timeout) }
-
-// if (!waitSecurityDelayDialogNew.isAdded)
-// waitSecurityDelayDialogNew.show(supportFragmentManager, WaitSecurityDelayDialogNew.TAG)
-
-
-// val readBeforeRequest = ReadBeforeRequest()
-// readBeforeRequest.timeout = timeout
-// EventBus.getDefault().post(readBeforeRequest)
- }
-
- override fun onReadAfterRequest() {
- LOG.i(TAG, "onReadAfterRequest")
- activity?.let { WaitSecurityDelayDialog.onReadAfterRequest(it) }
-
-// val readAfterRequest = ReadAfterRequest()
-// EventBus.getDefault().post(readAfterRequest)
- }
-
- override fun onReadWait(msec: Int) {
- LOG.i(TAG, "onReadWait msec $msec")
- activity?.let { WaitSecurityDelayDialog.onReadWait(it, msec) }
-
-// val readWait = ReadWait()
-// readWait.msec = msec
-// EventBus.getDefault().post(readWait)
- }
-
-}
\ No newline at end of file
diff --git a/app/src/tangemAccess/res/layout/fragment_confirm_transaction.xml b/app/src/tangemAccess/res/layout/fragment_confirm_transaction.xml
deleted file mode 100644
index 6bb5f43dda..0000000000
--- a/app/src/tangemAccess/res/layout/fragment_confirm_transaction.xml
+++ /dev/null
@@ -1,343 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/tangemAccess/res/layout/fragment_prepare_transaction.xml b/app/src/tangemAccess/res/layout/fragment_prepare_transaction.xml
deleted file mode 100644
index 7f675df2a3..0000000000
--- a/app/src/tangemAccess/res/layout/fragment_prepare_transaction.xml
+++ /dev/null
@@ -1,266 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/tangemAccess/res/layout/fragment_sign_transaction.xml b/app/src/tangemAccess/res/layout/fragment_sign_transaction.xml
deleted file mode 100644
index 19125f6911..0000000000
--- a/app/src/tangemAccess/res/layout/fragment_sign_transaction.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/tangemAccess/res/values/strings.xml b/app/src/tangemAccess/res/values/strings.xml
deleted file mode 100644
index 845dc9021a..0000000000
--- a/app/src/tangemAccess/res/values/strings.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
- Tangem
-
-
\ No newline at end of file
diff --git a/buildSrc/src/main/java/Dependency.kt b/buildSrc/src/main/java/Dependency.kt
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/common/src/main/java/com/tangem/common/Provider.kt b/common/src/main/java/com/tangem/common/Provider.kt
new file mode 100644
index 0000000000..7275695e98
--- /dev/null
+++ b/common/src/main/java/com/tangem/common/Provider.kt
@@ -0,0 +1,10 @@
+package com.tangem.common
+
+/**
+ * Provider for lazy initialization
+ *
+ * @param action initialization action
+ *
+[REDACTED_AUTHOR]
+ */
+class Provider(action: () -> T) : () -> T by action
\ No newline at end of file
diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/promotion/PromotionApi.kt b/core/datasource/src/main/java/com/tangem/datasource/api/promotion/PromotionApi.kt
new file mode 100644
index 0000000000..d71061c21a
--- /dev/null
+++ b/core/datasource/src/main/java/com/tangem/datasource/api/promotion/PromotionApi.kt
@@ -0,0 +1,29 @@
+package com.tangem.datasource.api.promotion
+
+import com.tangem.datasource.api.promotion.models.*
+import retrofit2.http.*
+
+/**
+ *
+ * Promotion API
+ * @see Documentation
+[REDACTED_AUTHOR]
+ */
+interface PromotionApi {
+
+ @Headers("Cache-Control: max-age=3600")
+ @GET("promotion")
+ suspend fun getPromotionInfo(@Query("programName") name: String): PromotionInfoResponse
+
+ @POST("promotion/code/validate")
+ suspend fun validateCode(@Body request: CodeValidateRequestBody): CodeValidateResponse
+
+ @POST("promotion/code/award")
+ suspend fun requestAwardByCode(@Body request: CodeAwardRequestBody): CodeAwardResponse
+
+ @POST("promotion/validate")
+ suspend fun validate(@Body request: ValidateRequestBody): ValidateResponse
+
+ @POST("promotion/award")
+ suspend fun requestAward(@Body request: AwardRequestBody): AwardResponse
+}
\ No newline at end of file
diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/promotion/models/AbstractPromotionResponse.kt b/core/datasource/src/main/java/com/tangem/datasource/api/promotion/models/AbstractPromotionResponse.kt
new file mode 100644
index 0000000000..edfc8e990d
--- /dev/null
+++ b/core/datasource/src/main/java/com/tangem/datasource/api/promotion/models/AbstractPromotionResponse.kt
@@ -0,0 +1,18 @@
+package com.tangem.datasource.api.promotion.models
+
+import com.squareup.moshi.Json
+
+/**
+[REDACTED_AUTHOR]
+ */
+abstract class AbstractPromotionResponse {
+
+ abstract val error: Error?
+
+ fun isError(): Boolean = error != null
+
+ data class Error(
+ @Json(name = "code") val code: Int,
+ @Json(name = "message") val message: String,
+ )
+}
\ No newline at end of file
diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/promotion/models/AwardRequestBody.kt b/core/datasource/src/main/java/com/tangem/datasource/api/promotion/models/AwardRequestBody.kt
new file mode 100644
index 0000000000..c8ac7faed1
--- /dev/null
+++ b/core/datasource/src/main/java/com/tangem/datasource/api/promotion/models/AwardRequestBody.kt
@@ -0,0 +1,12 @@
+package com.tangem.datasource.api.promotion.models
+
+import com.squareup.moshi.Json
+
+/**
+[REDACTED_AUTHOR]
+ */
+data class AwardRequestBody(
+ @Json(name = "walletId") val walletId: String,
+ @Json(name = "address") val address: String,
+ @Json(name = "programName") val programName: String,
+)
\ No newline at end of file
diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/promotion/models/AwardResponse.kt b/core/datasource/src/main/java/com/tangem/datasource/api/promotion/models/AwardResponse.kt
new file mode 100644
index 0000000000..c43c59fa45
--- /dev/null
+++ b/core/datasource/src/main/java/com/tangem/datasource/api/promotion/models/AwardResponse.kt
@@ -0,0 +1,11 @@
+package com.tangem.datasource.api.promotion.models
+
+import com.squareup.moshi.Json
+
+/**
+[REDACTED_AUTHOR]
+ */
+data class AwardResponse(
+ @Json(name = "status") val status: Boolean?,
+ @Json(name = "error") override val error: Error? = null,
+) : AbstractPromotionResponse()
\ No newline at end of file
diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/promotion/models/CodeAwardRequestBody.kt b/core/datasource/src/main/java/com/tangem/datasource/api/promotion/models/CodeAwardRequestBody.kt
new file mode 100644
index 0000000000..51e8626d4b
--- /dev/null
+++ b/core/datasource/src/main/java/com/tangem/datasource/api/promotion/models/CodeAwardRequestBody.kt
@@ -0,0 +1,12 @@
+package com.tangem.datasource.api.promotion.models
+
+import com.squareup.moshi.Json
+
+/**
+[REDACTED_AUTHOR]
+ */
+data class CodeAwardRequestBody(
+ @Json(name = "walletId") val walletId: String,
+ @Json(name = "address") val address: String,
+ @Json(name = "code") val code: String?,
+)
\ No newline at end of file
diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/promotion/models/CodeAwardResponse.kt b/core/datasource/src/main/java/com/tangem/datasource/api/promotion/models/CodeAwardResponse.kt
new file mode 100644
index 0000000000..33d9313c42
--- /dev/null
+++ b/core/datasource/src/main/java/com/tangem/datasource/api/promotion/models/CodeAwardResponse.kt
@@ -0,0 +1,11 @@
+package com.tangem.datasource.api.promotion.models
+
+import com.squareup.moshi.Json
+
+/**
+[REDACTED_AUTHOR]
+ */
+data class CodeAwardResponse(
+ @Json(name = "status") val status: Boolean?,
+ @Json(name = "error") override val error: Error? = null,
+) : AbstractPromotionResponse()
\ No newline at end of file
diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/promotion/models/CodeValidateRequestBody.kt b/core/datasource/src/main/java/com/tangem/datasource/api/promotion/models/CodeValidateRequestBody.kt
new file mode 100644
index 0000000000..769ecdad26
--- /dev/null
+++ b/core/datasource/src/main/java/com/tangem/datasource/api/promotion/models/CodeValidateRequestBody.kt
@@ -0,0 +1,11 @@
+package com.tangem.datasource.api.promotion.models
+
+import com.squareup.moshi.Json
+
+/**
+[REDACTED_AUTHOR]
+ */
+data class CodeValidateRequestBody(
+ @Json(name = "walletId") val walletId: String,
+ @Json(name = "code") val code: String?,
+)
\ No newline at end of file
diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/promotion/models/CodeValidateResponse.kt b/core/datasource/src/main/java/com/tangem/datasource/api/promotion/models/CodeValidateResponse.kt
new file mode 100644
index 0000000000..e6e87e0ff3
--- /dev/null
+++ b/core/datasource/src/main/java/com/tangem/datasource/api/promotion/models/CodeValidateResponse.kt
@@ -0,0 +1,11 @@
+package com.tangem.datasource.api.promotion.models
+
+import com.squareup.moshi.Json
+
+/**
+[REDACTED_AUTHOR]
+ */
+data class CodeValidateResponse(
+ @Json(name = "valid") val valid: Boolean?,
+ @Json(name = "error") override val error: Error? = null,
+) : AbstractPromotionResponse()
\ No newline at end of file
diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/promotion/models/PromotionInfoResponse.kt b/core/datasource/src/main/java/com/tangem/datasource/api/promotion/models/PromotionInfoResponse.kt
new file mode 100644
index 0000000000..ca5406aba5
--- /dev/null
+++ b/core/datasource/src/main/java/com/tangem/datasource/api/promotion/models/PromotionInfoResponse.kt
@@ -0,0 +1,40 @@
+package com.tangem.datasource.api.promotion.models
+
+import com.squareup.moshi.Json
+
+/**
+[REDACTED_AUTHOR]
+ */
+data class PromotionInfoResponse(
+ @Json(name = "newCard") val newCard: Data?,
+ @Json(name = "oldCard") val oldCard: Data?,
+ @Json(name = "awardPaymentToken") val awardPaymentToken: TokenData?,
+ @Json(name = "error") override val error: Error? = null,
+) : AbstractPromotionResponse() {
+
+ data class Data(
+ @Json(name = "status") val status: Status,
+ @Json(name = "award") val award: Double,
+ )
+
+ enum class Status(val value: String) {
+ @Json(name = "pending")
+ PENDING("pending"),
+
+ @Json(name = "active")
+ ACTIVE("active"),
+
+ @Json(name = "finished")
+ FINISHED("finished"),
+ }
+
+ data class TokenData(
+ @Json(name = "id") val id: String,
+ @Json(name = "name") val name: String,
+ @Json(name = "symbol") val symbol: String,
+ @Json(name = "active") val active: Boolean,
+ @Json(name = "networkId") val networkId: String,
+ @Json(name = "contractAddress") val contractAddress: String,
+ @Json(name = "decimalCount") val decimalCount: Int,
+ )
+}
\ No newline at end of file
diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/promotion/models/ValidateRequestBody.kt b/core/datasource/src/main/java/com/tangem/datasource/api/promotion/models/ValidateRequestBody.kt
new file mode 100644
index 0000000000..090f0e0d29
--- /dev/null
+++ b/core/datasource/src/main/java/com/tangem/datasource/api/promotion/models/ValidateRequestBody.kt
@@ -0,0 +1,11 @@
+package com.tangem.datasource.api.promotion.models
+
+import com.squareup.moshi.Json
+
+/**
+[REDACTED_AUTHOR]
+ */
+data class ValidateRequestBody(
+ @Json(name = "walletId") val walletId: String,
+ @Json(name = "programName") val programName: String,
+)
\ No newline at end of file
diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/promotion/models/ValidateResponse.kt b/core/datasource/src/main/java/com/tangem/datasource/api/promotion/models/ValidateResponse.kt
new file mode 100644
index 0000000000..97cd74645d
--- /dev/null
+++ b/core/datasource/src/main/java/com/tangem/datasource/api/promotion/models/ValidateResponse.kt
@@ -0,0 +1,11 @@
+package com.tangem.datasource.api.promotion.models
+
+import com.squareup.moshi.Json
+
+/**
+[REDACTED_AUTHOR]
+ */
+data class ValidateResponse(
+ @Json(name = "valid") val valid: Boolean?,
+ @Json(name = "error") override val error: Error? = null,
+) : AbstractPromotionResponse()
\ No newline at end of file
diff --git a/core/datasource/src/main/java/com/tangem/datasource/config/ConfigManager.kt b/core/datasource/src/main/java/com/tangem/datasource/config/ConfigManager.kt
index e3325c77c2..5cfaed8562 100644
--- a/core/datasource/src/main/java/com/tangem/datasource/config/ConfigManager.kt
+++ b/core/datasource/src/main/java/com/tangem/datasource/config/ConfigManager.kt
@@ -17,7 +17,6 @@ interface ConfigManager {
fun resetToDefault(name: String)
companion object {
- const val IS_SENDING_TO_PAY_ID_ENABLED = "isSendingToPayIdEnabled"
const val IS_CREATING_TWIN_CARDS_ALLOWED = "isCreatingTwinCardsAllowed"
const val IS_TOP_UP_ENABLED = "isTopUpEnabled"
}
diff --git a/core/datasource/src/main/java/com/tangem/datasource/config/ConfigManagerImpl.kt b/core/datasource/src/main/java/com/tangem/datasource/config/ConfigManagerImpl.kt
index 4f95438c33..1557e84bf1 100644
--- a/core/datasource/src/main/java/com/tangem/datasource/config/ConfigManagerImpl.kt
+++ b/core/datasource/src/main/java/com/tangem/datasource/config/ConfigManagerImpl.kt
@@ -1,13 +1,7 @@
package com.tangem.datasource.config
-import com.tangem.blockchain.common.BlockchainSdkConfig
-import com.tangem.blockchain.common.BlockchairCredentials
-import com.tangem.blockchain.common.GetBlockCredentials
-import com.tangem.blockchain.common.NowNodeCredentials
-import com.tangem.blockchain.common.QuickNodeCredentials
-import com.tangem.blockchain.common.TonCenterCredentials
+import com.tangem.blockchain.common.*
import com.tangem.datasource.config.ConfigManager.Companion.IS_CREATING_TWIN_CARDS_ALLOWED
-import com.tangem.datasource.config.ConfigManager.Companion.IS_SENDING_TO_PAY_ID_ENABLED
import com.tangem.datasource.config.ConfigManager.Companion.IS_TOP_UP_ENABLED
import com.tangem.datasource.config.models.Config
import com.tangem.datasource.config.models.ConfigModel
@@ -34,7 +28,6 @@ internal class ConfigManagerImpl @Inject constructor() : ConfigManager {
override fun turnOff(name: String) {
when (name) {
- IS_SENDING_TO_PAY_ID_ENABLED -> config = config.copy(isSendingToPayIdEnabled = false)
IS_TOP_UP_ENABLED -> config = config.copy(isTopUpEnabled = false)
IS_CREATING_TWIN_CARDS_ALLOWED -> config = config.copy(isCreatingTwinCardsAllowed = false)
}
@@ -42,13 +35,13 @@ internal class ConfigManagerImpl @Inject constructor() : ConfigManager {
override fun resetToDefault(name: String) {
when (name) {
- IS_SENDING_TO_PAY_ID_ENABLED ->
- config =
- config.copy(isSendingToPayIdEnabled = defaultConfig.isSendingToPayIdEnabled)
- IS_TOP_UP_ENABLED -> config = config.copy(isTopUpEnabled = defaultConfig.isTopUpEnabled)
- IS_CREATING_TWIN_CARDS_ALLOWED ->
- config =
- config.copy(isCreatingTwinCardsAllowed = defaultConfig.isCreatingTwinCardsAllowed)
+ IS_TOP_UP_ENABLED -> {
+ config = config.copy(isTopUpEnabled = defaultConfig.isTopUpEnabled)
+ }
+ IS_CREATING_TWIN_CARDS_ALLOWED -> {
+ config = config.copy(isCreatingTwinCardsAllowed = defaultConfig.isCreatingTwinCardsAllowed)
+ }
+ else -> Unit
}
}
@@ -57,12 +50,11 @@ internal class ConfigManagerImpl @Inject constructor() : ConfigManager {
config = config.copy(
isTopUpEnabled = model.isTopUpEnabled,
- isSendingToPayIdEnabled = model.isSendingToPayIdEnabled,
isCreatingTwinCardsAllowed = model.isCreatingTwinCardsAllowed,
)
+
defaultConfig = defaultConfig.copy(
isTopUpEnabled = model.isTopUpEnabled,
- isSendingToPayIdEnabled = model.isSendingToPayIdEnabled,
isCreatingTwinCardsAllowed = model.isCreatingTwinCardsAllowed,
)
}
@@ -111,6 +103,7 @@ internal class ConfigManagerImpl @Inject constructor() : ConfigManager {
zendesk = configValues.zendesk,
swapReferrerAccount = configValues.swapReferrerAccount,
walletConnectProjectId = configValues.walletConnectProjectId,
+ tangemComAuthorization = configValues.tangemComAuthorization,
)
}
}
\ No newline at end of file
diff --git a/core/datasource/src/main/java/com/tangem/datasource/config/models/Config.kt b/core/datasource/src/main/java/com/tangem/datasource/config/models/Config.kt
index 24d8735376..3d0bf5be7f 100644
--- a/core/datasource/src/main/java/com/tangem/datasource/config/models/Config.kt
+++ b/core/datasource/src/main/java/com/tangem/datasource/config/models/Config.kt
@@ -11,7 +11,6 @@ data class Config(
val appsFlyerDevKey: String = "",
val amplitudeApiKey: String = "",
val blockchainSdkConfig: BlockchainSdkConfig = BlockchainSdkConfig(),
- val isSendingToPayIdEnabled: Boolean = true,
val isTopUpEnabled: Boolean = false,
@Deprecated("Not relevant since version 3.23")
val isCreatingTwinCardsAllowed: Boolean = false,
@@ -19,4 +18,5 @@ data class Config(
val zendesk: ZendeskConfig? = null,
val swapReferrerAccount: SwapReferrerAccount? = null,
val walletConnectProjectId: String = "",
+ val tangemComAuthorization: String? = null,
)
\ No newline at end of file
diff --git a/core/datasource/src/main/java/com/tangem/datasource/config/models/JsonModels.kt b/core/datasource/src/main/java/com/tangem/datasource/config/models/JsonModels.kt
index cd518d4c31..2e195247a6 100644
--- a/core/datasource/src/main/java/com/tangem/datasource/config/models/JsonModels.kt
+++ b/core/datasource/src/main/java/com/tangem/datasource/config/models/JsonModels.kt
@@ -8,7 +8,6 @@ import com.squareup.moshi.Json
class FeatureModel(
val isTopUpEnabled: Boolean,
- val isSendingToPayIdEnabled: Boolean,
val isCreatingTwinCardsAllowed: Boolean,
)
@@ -38,6 +37,7 @@ class ConfigValueModel(
val swapReferrerAccount: SwapReferrerAccount?,
val kaspaSecondaryApiUrl: String,
val walletConnectProjectId: String,
+ val tangemComAuthorization: String?,
)
data class AppsFlyer(
diff --git a/core/datasource/src/main/java/com/tangem/datasource/di/NetworkModule.kt b/core/datasource/src/main/java/com/tangem/datasource/di/NetworkModule.kt
index 4ecc2b2529..c8ae82faa9 100644
--- a/core/datasource/src/main/java/com/tangem/datasource/di/NetworkModule.kt
+++ b/core/datasource/src/main/java/com/tangem/datasource/di/NetworkModule.kt
@@ -2,10 +2,13 @@ package com.tangem.datasource.di
import com.squareup.moshi.Moshi
import com.tangem.datasource.api.paymentology.PaymentologyApi
+import com.tangem.datasource.api.promotion.PromotionApi
import com.tangem.datasource.api.tangemTech.TangemTechApi
import com.tangem.datasource.utils.RequestHeader.*
import com.tangem.datasource.utils.addHeaders
import com.tangem.datasource.utils.allowLogging
+import com.tangem.lib.auth.AuthProvider
+import com.tangem.lib.auth.BuildConfig
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
@@ -13,6 +16,7 @@ import dagger.hilt.components.SingletonComponent
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory
+import java.util.concurrent.TimeUnit
import javax.inject.Singleton
@Module
@@ -54,10 +58,37 @@ class NetworkModule {
.create(PaymentologyApi::class.java)
}
+ @Provides
+ @Singleton
+ @PromotionOneInch
+ fun providePromotionOneInchApi(authProvider: AuthProvider, @NetworkMoshi moshi: Moshi): PromotionApi {
+ val okClient = OkHttpClient.Builder()
+ .addHeaders(
+ AuthenticationHeader(authProvider),
+ )
+ .allowLogging()
+ .callTimeout(API_ONE_INCH_TIMEOUT_MS, TimeUnit.MILLISECONDS)
+ .connectTimeout(API_ONE_INCH_TIMEOUT_MS, TimeUnit.MILLISECONDS)
+ .readTimeout(API_ONE_INCH_TIMEOUT_MS, TimeUnit.MILLISECONDS)
+ .writeTimeout(API_ONE_INCH_TIMEOUT_MS, TimeUnit.MILLISECONDS)
+ .build()
+ return createBasePromotionRetrofit(okClient, moshi)
+ }
+
+ private fun createBasePromotionRetrofit(okHttpClient: OkHttpClient, moshi: Moshi): PromotionApi {
+ return Retrofit.Builder()
+ .addConverterFactory(MoshiConverterFactory.create(moshi))
+ .baseUrl(if (BuildConfig.DEBUG) DEV_TANGEM_TECH_BASE_URL else PROD_TANGEM_TECH_BASE_URL)
+ .client(okHttpClient)
+ .build()
+ .create(PromotionApi::class.java)
+ }
+
private companion object {
const val PROD_TANGEM_TECH_BASE_URL = "https://api.tangem-tech.com/v1/"
const val DEV_TANGEM_TECH_BASE_URL = "https://devapi.tangem-tech.com/v1/"
- private const val PAYMENTOLOGY_BASE_URL: String = "https://paymentologygate.oa.r.appspot.com/"
+ const val PAYMENTOLOGY_BASE_URL: String = "https://paymentologygate.oa.r.appspot.com/"
+ const val API_ONE_INCH_TIMEOUT_MS = 5000L
}
}
\ No newline at end of file
diff --git a/core/datasource/src/main/java/com/tangem/datasource/di/PromotionOneInch.kt b/core/datasource/src/main/java/com/tangem/datasource/di/PromotionOneInch.kt
new file mode 100644
index 0000000000..9e2d6b3981
--- /dev/null
+++ b/core/datasource/src/main/java/com/tangem/datasource/di/PromotionOneInch.kt
@@ -0,0 +1,8 @@
+package com.tangem.datasource.di
+
+import javax.inject.Qualifier
+
+@Qualifier
+@MustBeDocumented
+@Retention(AnnotationRetention.RUNTIME)
+annotation class PromotionOneInch
\ No newline at end of file
diff --git a/core/datasource/src/main/java/com/tangem/datasource/utils/HttpClientExt.kt b/core/datasource/src/main/java/com/tangem/datasource/utils/HttpClientExt.kt
index dffc98c05a..4fd16a0d1d 100644
--- a/core/datasource/src/main/java/com/tangem/datasource/utils/HttpClientExt.kt
+++ b/core/datasource/src/main/java/com/tangem/datasource/utils/HttpClientExt.kt
@@ -13,7 +13,7 @@ internal fun OkHttpClient.Builder.addHeaders(vararg requestHeaders: RequestHeade
val request = chain.request().newBuilder().apply {
requestHeaders
.flatMap(RequestHeader::values)
- .forEach { addHeader(it.first, it.second) }
+ .forEach { addHeader(it.first, it.second.invoke()) }
}.build()
chain.proceed(request)
diff --git a/core/datasource/src/main/java/com/tangem/datasource/utils/RequestHeader.kt b/core/datasource/src/main/java/com/tangem/datasource/utils/RequestHeader.kt
index 66d6c0f90b..5e5067746f 100644
--- a/core/datasource/src/main/java/com/tangem/datasource/utils/RequestHeader.kt
+++ b/core/datasource/src/main/java/com/tangem/datasource/utils/RequestHeader.kt
@@ -7,15 +7,15 @@ import com.tangem.lib.auth.AuthProvider
*
* @param pairs header name and header value pairs
*/
-sealed class RequestHeader(vararg pairs: Pair) {
+sealed class RequestHeader(vararg pairs: Pair String>) {
/** Header list */
- val values: List> = pairs.toList()
+ val values: List String>> = pairs.toList()
- object CacheControlHeader : RequestHeader("Cache-Control" to "max-age=600")
+ object CacheControlHeader : RequestHeader("Cache-Control" to { "max-age=600" })
class AuthenticationHeader(authProvider: AuthProvider) : RequestHeader(
- "card_public_key" to authProvider.getCardPublicKey(),
- "card_id" to authProvider.getCardId(),
+ "card_id" to { authProvider.getCardId() },
+ "card_public_key" to { authProvider.getCardPublicKey() },
)
}
\ No newline at end of file
diff --git a/core/featuretoggles/src/main/assets/configs/feature_toggles_config.json b/core/featuretoggles/src/main/assets/configs/feature_toggles_config.json
index ab2ed7ee14..d0e3fddbe4 100644
--- a/core/featuretoggles/src/main/assets/configs/feature_toggles_config.json
+++ b/core/featuretoggles/src/main/assets/configs/feature_toggles_config.json
@@ -9,10 +9,18 @@
},
{
"name": "NEW_CARD_SCANNING_ENABLED",
- "version": "4.9.0"
+ "version": "4.10.0"
},
{
"name": "REDESIGNED_WALLET_SCREEN_ENABLED",
"version": "undefined"
+ },
+ {
+ "name": "1INCH_LEARN_2_EARN_ENABLED",
+ "version": "undefined"
+ },
+ {
+ "name": "REDESIGNED_TOKEN_DETAIL_SCREEN_ENABLED",
+ "version": "undefined"
}
-]
\ No newline at end of file
+]
diff --git a/core/navigation/.gitignore b/core/navigation/.gitignore
new file mode 100644
index 0000000000..42afabfd2a
--- /dev/null
+++ b/core/navigation/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/core/navigation/build.gradle.kts b/core/navigation/build.gradle.kts
new file mode 100644
index 0000000000..bb00481f67
--- /dev/null
+++ b/core/navigation/build.gradle.kts
@@ -0,0 +1,14 @@
+plugins {
+ alias(deps.plugins.android.library)
+ alias(deps.plugins.kotlin.android)
+ id("configuration")
+}
+
+android {
+ namespace = "com.tangem.core.navigation"
+}
+
+dependencies {
+ implementation(deps.material)
+ implementation(deps.reKotlin)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/common/redux/navigation/FragmentShareTransition.kt b/core/navigation/src/main/java/com/tangem/core/navigation/FragmentShareTransition.kt
similarity index 94%
rename from app/src/main/java/com/tangem/tap/common/redux/navigation/FragmentShareTransition.kt
rename to core/navigation/src/main/java/com/tangem/core/navigation/FragmentShareTransition.kt
index ab7aa07259..2cb2132eec 100644
--- a/app/src/main/java/com/tangem/tap/common/redux/navigation/FragmentShareTransition.kt
+++ b/core/navigation/src/main/java/com/tangem/core/navigation/FragmentShareTransition.kt
@@ -1,4 +1,4 @@
-package com.tangem.tap.common.redux.navigation
+package com.tangem.core.navigation
import android.view.View
import androidx.transition.TransitionSet
diff --git a/app/src/main/java/com/tangem/tap/common/redux/navigation/NavigationAction.kt b/core/navigation/src/main/java/com/tangem/core/navigation/NavigationAction.kt
similarity index 83%
rename from app/src/main/java/com/tangem/tap/common/redux/navigation/NavigationAction.kt
rename to core/navigation/src/main/java/com/tangem/core/navigation/NavigationAction.kt
index 71f3274e4c..082ada57ae 100644
--- a/app/src/main/java/com/tangem/tap/common/redux/navigation/NavigationAction.kt
+++ b/core/navigation/src/main/java/com/tangem/core/navigation/NavigationAction.kt
@@ -1,4 +1,4 @@
-package com.tangem.tap.common.redux.navigation
+package com.tangem.core.navigation
import android.net.Uri
import android.os.Bundle
@@ -7,6 +7,7 @@ import org.rekotlin.Action
import java.lang.ref.WeakReference
sealed class NavigationAction : Action {
+
data class NavigateTo(
val screen: AppScreen,
val fragmentShareTransition: FragmentShareTransition? = null,
@@ -14,10 +15,7 @@ sealed class NavigationAction : Action {
val bundle: Bundle? = null,
) : NavigationAction()
- data class PopBackTo(
- val screen: AppScreen? = null,
- val inclusive: Boolean = false,
- ) : NavigationAction()
+ data class PopBackTo(val screen: AppScreen? = null, val inclusive: Boolean = false) : NavigationAction()
data class OpenUrl(val url: String) : NavigationAction()
@@ -28,5 +26,6 @@ sealed class NavigationAction : Action {
data class Share(val data: String) : NavigationAction()
data class ActivityCreated(val activity: WeakReference) : NavigationAction()
+
data class ActivityDestroyed(val activity: WeakReference) : NavigationAction()
}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/common/redux/navigation/NavigationState.kt b/core/navigation/src/main/java/com/tangem/core/navigation/NavigationState.kt
similarity index 57%
rename from app/src/main/java/com/tangem/tap/common/redux/navigation/NavigationState.kt
rename to core/navigation/src/main/java/com/tangem/core/navigation/NavigationState.kt
index 861a0a0fb9..db33dd330d 100644
--- a/app/src/main/java/com/tangem/tap/common/redux/navigation/NavigationState.kt
+++ b/core/navigation/src/main/java/com/tangem/core/navigation/NavigationState.kt
@@ -1,4 +1,4 @@
-package com.tangem.tap.common.redux.navigation
+package com.tangem.core.navigation
import androidx.appcompat.app.AppCompatActivity
import org.rekotlin.StateType
@@ -9,17 +9,25 @@ data class NavigationState(
val activity: WeakReference? = null,
) : StateType
-enum class AppScreen(
- val isDialogFragment: Boolean = false,
-) {
+enum class AppScreen(val isDialogFragment: Boolean = false) {
Home,
Shop,
Disclaimer,
- OnboardingNote, OnboardingWallet, OnboardingTwins, OnboardingOther,
- Wallet, WalletDetails,
+ OnboardingNote,
+ OnboardingWallet,
+ OnboardingTwins,
+ OnboardingOther,
+ Wallet,
+ WalletDetails,
Send,
- Details, DetailsSecurity, CardSettings, AppSettings, ResetToFactory, AccessCodeRecovery,
- AddTokens, AddCustomToken,
+ Details,
+ DetailsSecurity,
+ CardSettings,
+ AppSettings,
+ ResetToFactory,
+ AccessCodeRecovery,
+ AddTokens,
+ AddCustomToken,
WalletConnectSessions,
QrScan,
ReferralProgram,
diff --git a/core/navigation/src/main/java/com/tangem/core/navigation/NavigationStateHolder.kt b/core/navigation/src/main/java/com/tangem/core/navigation/NavigationStateHolder.kt
new file mode 100644
index 0000000000..7504b75656
--- /dev/null
+++ b/core/navigation/src/main/java/com/tangem/core/navigation/NavigationStateHolder.kt
@@ -0,0 +1,12 @@
+package com.tangem.core.navigation
+
+/**
+ * Navigation state holder
+ *
+[REDACTED_AUTHOR]
+ */
+interface NavigationStateHolder {
+
+ /** Navigate by [action] */
+ fun navigate(action: NavigationAction)
+}
\ No newline at end of file
diff --git a/core/res/src/main/res/values-de/strings.xml b/core/res/src/main/res/values-de/strings.xml
index 3e71b3a98a..93537cff03 100644
--- a/core/res/src/main/res/values-de/strings.xml
+++ b/core/res/src/main/res/values-de/strings.xml
@@ -12,6 +12,7 @@
Erledigt
OK
Änderungen speichern
+ Absenden
Erfolg
Zugangscode
Sie müssen den richtigen Zugangscode eingeben, bevor Sie die Karte scannen.
@@ -34,11 +35,7 @@
Der Betrag enthält nicht einige Ihrer Mittel
Betrag
Adresse
- Adresse oder PayString
Die Adresse stimmt mit der Adresse Ihrer Brieftasche überein
- PayString ist nicht registriert
- PayString-Anfrage ist fehlgeschlagen
- PayString wird von der Blockchain nicht unterstützt
Tag
Memo
inkl. Gebühr
@@ -48,7 +45,6 @@
Priorität
Höchstbetrag
Netzgebühr
- Absenden
Gesamt
%1$s und %2$s werden gesendet
≈ %1$s (inkl. Gebühr: %2$s)
@@ -57,11 +53,9 @@
Ungültige Adresse
Tangem Wallet
Tangem Twin
- PayString erstellen
Die Bilanz wird aufgeladen…
Die Transaktion läuft…
Verifizierte Bilanz
- Absenden
WalletConnect
Das Konto ist nicht erstellt
Diese Karte wird nicht unterstützt
diff --git a/core/res/src/main/res/values-fr/strings.xml b/core/res/src/main/res/values-fr/strings.xml
index 01059b36ff..529af080aa 100644
--- a/core/res/src/main/res/values-fr/strings.xml
+++ b/core/res/src/main/res/values-fr/strings.xml
@@ -12,6 +12,7 @@
Exécuté
OK
Sauvegarder les modifications
+ Envoyer
Avec succès
Code d\'accès
Vous devrez entrer le mot de passe correct avant de scanner la carte
@@ -34,11 +35,7 @@
Le montant n\'inclut pas certains de vos fonds
Somme
Adresse
- Adresse ou PayString
L\'adresse est la même que celle de votre portefeuille
- PayString non enregistré
- La demande de PayString a échoué
- PayString non pris en charge par la blockchain
Tag
Memo
Inclure les commissions
@@ -48,7 +45,6 @@
Priorité
Somme maximale
Commissions du réseau
- Envoyer
Total
Sera envoyé %1$s et %2$s
≈ %1$s (incl. les commissions : %2$s)
@@ -57,11 +53,9 @@
Adresse incorrecte
Tangem Wallet
Tangem Twin
- Créer PayString
Solde est en cours de téléchargement…
Transaction en cours…
Solde confirmé
- Envoyer
WalletConnect
Compte n\'est pas créé
Cette carte n\'est pas prise en charge
diff --git a/core/res/src/main/res/values-it/strings.xml b/core/res/src/main/res/values-it/strings.xml
index bc24145f51..3c294f6376 100644
--- a/core/res/src/main/res/values-it/strings.xml
+++ b/core/res/src/main/res/values-it/strings.xml
@@ -12,6 +12,7 @@
Fatto
OK
Mantieni le modifiche
+ Invia
Con successo
Codice di accesso
Prima di scansionare la carta sarà necessario inserire il codice di accesso corretto
@@ -34,11 +35,7 @@
L\'importo non include alcuni dei tuoi fondi
Importo
Indirizzo
- Indirizzo o PayString
L\'indirizzo corrisponde all\'indirizzo del tuo portafoglio
- PayString non registrato
- Richiesta PayString fallita
- PayString non supportato dalla blockchain
Tag
Memo
Includi commissione
@@ -48,7 +45,6 @@
Prioritario
Importo totale
Costi della rete
- Invia
Totale
Sarà inviato %1$s e %2$s
≈ %1$s (inc. commissione: %2$s)
@@ -57,11 +53,9 @@
Indirizzo non valido
Tangem Wallet
Tangem Twin
- Crea PayString
Il saldo sta per essere caricato…
Transazione in corso…
Saldo verificato
- Invia
WalletConnect
Conto non creato
Questa carta non è supportata
diff --git a/core/res/src/main/res/values-ru/strings.xml b/core/res/src/main/res/values-ru/strings.xml
index 57b1b1dcae..797b9dea53 100644
--- a/core/res/src/main/res/values-ru/strings.xml
+++ b/core/res/src/main/res/values-ru/strings.xml
@@ -15,7 +15,7 @@
Эта карта не является платежным средством. В настоящее время мы не можем сопоставить количество подписей на карте с информацией в блокчейне. Это нормально, но в редких случаях может означать, что предыдущий владелец удерживает подписанную транзакцию от публикации, что является поводом для беспокойства.\nНе принимайте эту карту в качестве физического платежа от кого-то, кому вы не доверяете.\nВо всех остальных отношениях эта карта совершенно безопасна.\nTangem — единственный аппаратный кошелек, предлагающий защиту методом подсчета подписей.
У вас возникли трудности со сканированием карты?
Эта карта не предназначена для работы с этим приложением
- Перейдите в настройки, чтобы включить биометрическую аутентификацию в приложении Tangem App
+ Перейдите в настройки, чтобы включить биометрическую аутентификацию в приложении Tangem
Включите биометрическую аутентификацию
Все сохраненные коды доступа будут удалены. Вам потребуется вводить код доступа при работе с кошельком.
При отключении функции сохранения кошелька все ранее сохраненные кошельки будут удалены из приложения.
@@ -39,7 +39,7 @@
Восстановление кода доступа
Смена кода доступа
Код доступа будет изменен только на данной карте
- Сброс к заводским настройкам
+ Заводские настройки
Тип безопасности
Настройки карты
Tangem Bot
@@ -52,27 +52,42 @@
Баланс: %s
биометрическую аутентификацию
биометрией
+ Купить
Вы не предоставили доступ к камере, пожалуйста, измените настройки конфиденциальности.
Отмена
Закрыть
Копировать
+ Скопировать адрес
Создать
Удалить
Отключено
+ Не нравится
Готово
Включить
Включено
+ Обменять
+ Посмотреть историю транзакций
Обозреватель
+ Учись и получай бонусы!
+ Нравится
+ Основная сеть
Нет
- Ок
+ Нет данных
+ OK
Основная карта
+ Получить
Отклонить
+ Перезагрузить
Сохранить изменения
Искать
+ Секретная фраза
+ Продать
+ Отправить
Сервер недоступен, повторите попытку позднее
Поделиться
Подписать
Подписать и отправить
+ Стейкинг
Начать
Отправить
Успешно
@@ -81,6 +96,7 @@
Транзакции
Перевод
Я понял
+ Недоступно
Да
Адрес контракта скопирован!
Доступные сети
@@ -145,11 +161,20 @@
Приложите карту
Внутренняя ошибка: не удается найти менеджер кошельков
Вы обновили данные биометрии, отсканируйте свою карту для входа
+ Вы успешно прошли все уроки и теперь можете получить 1INCH токены
+
+ - Пройдите 3 урока и получите %d 1INCH токен на свой кошелек
+ - Пройдите 3 урока и получите %d 1INCH токена на свой кошелек
+ - Пройдите 3 урока и получите %d 1INCH токена на свой кошелек
+ - Пройдите 3 урока и получите %d 1INCH токенов на свой кошелек
+
Управление токенами
Чтобы защитить свои активы, мы советуем вам выполнить эту процедуру
Бэкап кошелька не был произведен
Баланс
В сумме учтены не все монеты
+ 1INCH токены будут зачислены на адрес вашего кошелька в сети %s в течение 24 часов
+ По вашему промокоду не было покупки кошелька, а значит вы не можете получить бонус. Купите кошелек Tangem, отсканируйте его в приложении и получите бонус.
Чтобы получить доступ ко всем сетям, вам необходимо отсканировать карту
Отсканируйте карту
Вам необходимо установить единый код доступа для защиты всех ваших карт
@@ -173,11 +198,8 @@
Запросить
Перейти к моему кошельку
Завершение бэкапа
- Верифицировать (Utorg)
- Обновить
Установить Код доступа
Получить криптовалюту
- Зарегистрироваться
Сканировать основную карту
Пропустить
Как это работает?
@@ -192,19 +214,9 @@
В этом случае вам будет необходимо начать процесс заново.
Вы хотите выйти из процесса активации?
Подготовка
- Другой кошелек уже был создан на карте, которую вы пытаетесь добавить. Хотите сбросить его и использовать карту для бэкапа?
- Подтвердите свою личность
- Верификация клиента
Код доступа
Подключиться
Резервная копия
- Приложите SaltPay карту
- Для начала процесса бэкапа вам необходимо добавить Tangem карту
- Завершите процесс бэкапа создав код доступа
- Приложите Tangem карту
- Бэкап карта не добавлена
- Бэкап карта создана
- Приготовьте SaltPay карту
Читать про секретную фразу
Запишите эти 12 слов в порядке, указанном ниже, и сохраните их в надежном месте.
Ваша секретная фраза
@@ -220,13 +232,8 @@
Итак, проверим
Для начала работы просто запросите начисление wxDAI на свой кошелек
Это займет несколько секунд
- Более подробная информация отправлена на ваш адрес электронной почты.
- Для начала работы с картой вам необходимо завершить процесс подтверждения личности
- Пожалуйста дождитесь завершения процесса подтверждения личности. Вы будете уведомлены через e-mail. Обычно это занимает не более часа. Вы можете закрыть приложение и вернуться позже.
Чтобы начать процесс резервного копирования, добавьте одну или две резервные карты.
Вы можете добавить еще одну карту или завершить процесс резервного копирования
- Установите 4-х значный код.\nОн будет использован для платежей.
- Подключите вашу карту к децентрализованной платежной системе
Подготовьте резервную карту с номером %s
Подготовьте основную карту
Подготовьте основную карту с номером %s
@@ -237,13 +244,9 @@
Резервная карта #%d
Запросить %s
Запрашивается
- Что-то пошло не так
- Подтвердите свою личность
- Подтверждение личности в процессе
Нет резервных карт
Добавлена одна резервная карта
Код доступа
- Подключите свою карту
Подготовьте свою карту
Добавлены две резервные карты
Пополните кошелек на любую сумму, чтобы начать пользоваться картой
@@ -264,6 +267,9 @@
Группировка
По балансу
Сортировка токенов
+ Разгруппировать
+ %1$s %2$s адрес в сети %3$s
+ %1$s (%2$s) в сети %3$s
Участвовать
Не удалось загрузить информацию по реферальной программе. Пожалуйста, попробуйте позже.
Не удалось загрузить информацию по реферальной программе. Код ошибки: %s. Пожалуйста, попробуйте позже.
@@ -295,12 +301,6 @@
Сброс к заводским настройкам приведет к полному удалению кошелька с выбранной карты. Вы не сможете восстановить текущий кошелек.
У вас есть карта банка другой страны или платежной системы UnionPay?
Карты банков РФ в данный момент не принимаются
- Приложите карту с логотипом Visa
- Внимание
- Пожалуйста обратитесь в службу поддержки
- Недостаточно средств для активации
- Данный Код доступа может быть легко взломан
- Ввод одинаковых цифр является не безопасным
Войдите в приложение и следите за своим балансом без сканирования карты
Доступ в приложение
Использовать биометрию
@@ -317,11 +317,7 @@
Поиск валют
Сумма
Адрес
- Адрес или PayString
Адрес совпадает с адресом кошелька
- PayString не зарегистрирован
- Не удалось выполнить запрос PayString
- PayString не поддерживается блокчейном
Недопустимый Tag. Он не будет добавлен в транзакцию.
Недопустимый Memo. Он не будет добавлен в транзакцию.
Tag
@@ -333,7 +329,6 @@
Приоритетная
Максимальная сумма
Сетевая комиссия
- Отправить
Отправка %s
Всего
%1$s и %2$s будет отправлено
@@ -350,6 +345,7 @@
Сеть Solana взимает арендную плату в размере %1$s каждые 2 дня. Аккаунты, которые не могут позволить себе арендную плату, удаляются из сети. Пополните свой счет более чем на %2$s, чтобы не платить арендную плату.
Держите свои криптосбережения в безопасности. Приватные ключи надежно хранятся на карте.
Революционный аппаратный кошелек
+ До **трех карт** с одним кошельком
До
трех карт
с одним кошельком
@@ -358,6 +354,8 @@
Тысячи криптовалют
Используйте его на ходу, в любом месте, в любое время. Без проводов и батареек. Как только понадобится крипта, просто приложите карту к телефону.
Кошелек для каждого
+ Пройдите 3 урока, получите скидку на покупку Tangem Wallet и 1INCH токены
+ Пройти обучение
Занимайте
Покупайте
Обменивайте
@@ -410,6 +408,7 @@
Скрыть токен
%1$s — это токен в сети %2$s. Чтобы отправить транзакцию %3$s, необходимо пополнить баланс %4$s (%5$s) для оплаты комиссии сети.
Пожалуйста, дождитесь завершения транзакции %s, чтобы иметь возможность отправить средства
+ %1$s токен в сети %%image%% %2$s
Токен %1$s является основной валютой в сети %2$s и не может быть скрыт до тех пор, пока у вас в списке есть другие токены этой сети.
Невозможно скрыть %s
Нет цены
@@ -424,6 +423,7 @@
Не удалось загрузить историю транзакций.\nНажмите на кнопку перезагрузки, чтобы обновить информацию.
История транзакций в настоящее время не поддерживается для этого блокчейна. Но не волнуйтесь, мы работаем над этим! А пока вы можете проверить ее в обозревателе.
от: %s
+ на: %s
В процессе…
Вы отсканировали ту же карту. Для создания twin-кошелька вам необходимо отсканировать карту с номером %d
Это карта, которую вы держите в руках. У парной карты номер %s.\n\nОбе карты можно использовать для вывода средств из этого кошелька.
@@ -445,7 +445,6 @@
Одновалютные
Мои кошельки
Разблокировать все с %s
- Создать PayString
История транзакций
Сеть недоступна
Блокчейн недоступен. Попробуй позже.
@@ -454,21 +453,26 @@
Транзакция подтверждается…
Подтвержденный баланс
Действия
- Купить
- Продать
- Отправить
Вы хотите купить или продать криптовалюту?
Запрос на подпись сообщения.\n\n%s
Dapp %1$s, запрос на\nподпись транзакции с BNB.\n\n%2$s
Торговый ордер на %1$s\nЦена: %2$s\nСумма к получению: %3$s\nСумма к оплате: %4$s
Детали транзакции:\nОт: %1$s\nК: %2$s\nСумма: %3$s
+ Транзакция с BNB успешно подписана и отправлена в Dapp.
Буфер обмена содержит код WalletConnect. Использовать скопированное значение или отсканировать QR-код
Запрос на создание транзакции для %1$s\n%2$s\n\nСумма: %3$s\nКомиссия: %4$s\nВсего: %5$s\nБаланс: %6$s
Невозможно отправить транзакцию. Недостаточно средств.
Не удалось установить сессию WalletConnect. Пожалуйста, повторите попытку позже.
+ Не все токены добавлены в ваш список. Пожалуйста, добавьте их в начале, а потом попробуйте снова. Недостающие токены: \n
+ Не удалось подписать сообщение.\nПожалуйста, попробуйте еще раз
Не удалось установить сессию WalletConnect за отведённое время. Пожалуйста, повторите попытку позже.
Запрос на подключение через WalletConnect содержит неподдерживаемые блокчеины. Неподдерживаемые блокчеины:\n
Cоединение с этим Dapp сервисом не может быть установлено из-за его технической реализации.
+ Произошла непредвиденная ошибка. Сообщение ошибки: %s Попробуйте, пожалуйста, позже. Если проблема будет продолжать возникать - обратитесь в службу поддержки.
+ Неверная карта выбрана в приложении Tangem
+ Не удалось создать транзакцию из данных Dapp. Код: %s
+ Произошла непредвиденная ошибка. Код ошибки: %d Попробуйте, пожалуйста, позже. Если проблема будет продолжать возникать - обратитесь в службу поддержки.
+ Сообщение было успешно подписано и отправлено в Dapp
Сеть %s не найдена. Пожалуйста, добавьте её и попробуйте заново.
Вставить из буфера обмена
Запрос на открытие сессии для\n%1$s\n\nСЕТЬ: %2$s\n\nURL: %3$s
@@ -477,12 +481,18 @@
Эту карту нельзя использовать с WalletConnect.
Сеть не поддерживается. Пожалуйста, выберите другую сеть.
Выберите сеть
+ Dapp не предоставил необходимые данные для открытия сессии WalletConnect
Подключение к Dapps
WalletConnect
+ Транзакция успешно подписана и отправлена в Dapp
+ Транзакция успешно подписана и отправлена в блокчейн
+ Не удалось найти хэш транзакции
Сеть %s
Аккаунт не создан
Эта карта не поддерживается
Ваша карта Tangem предназначена для работы с другим приложением. Пожалуйста, ознакомьтесь с названием и инструкциями на вашей карте и установите правильное приложение.
+ Рыночная цена %s
+ за 24 часа
Сеть %s
Адрес скопирован в буфер обмена
Нет соединения с интернетом
diff --git a/core/res/src/main/res/values-zh-rTW/strings.xml b/core/res/src/main/res/values-zh-rTW/strings.xml
index 597be9911d..ccb6abe736 100644
--- a/core/res/src/main/res/values-zh-rTW/strings.xml
+++ b/core/res/src/main/res/values-zh-rTW/strings.xml
@@ -46,23 +46,29 @@
餘額: %s
生物識別
生物
+ 購買
您尚未授予相機訪問權限,請更改您的隱私設置
刪除
關閉
複製
+ 複製地址
創造
刪除
禁用
+ 不喜歡
完成
允許
啟用
交易
+ 喜歡
否
OK
主卡片
拒絕
保存設置
搜索
+ 銷售
+ 發送
伺服器不可用,請稍後在試
分享
簽署
@@ -74,6 +80,7 @@
條款和條件
交易
我了解
+ 無法觸達
是
已複製代幣地址
支持的網路
@@ -164,11 +171,8 @@
獲取
繼續至我的錢包
完成備份過程
- 通過Utorg驗證
- 刷新
設置PIN碼
接收貨幣
- 註冊
掃描主卡
暫時略過
它是如何運作的?
@@ -183,18 +187,9 @@
這此情況,您必須要重新開始
您想要離開啟用程序嗎?
開始
- 驗證身分
- KYC
PIN 碼
連接
創建備份
- 點擊 SaltPay 卡
- 要開始備份過程,您必須添加 Tangem 卡片作為備份
- 通過創建訪問密碼完成備份
- 點擊 Tangem 卡片
- 沒有備份卡片
- 備份卡片已準備完成
- 準備SaltPay卡
閱讀更多關於助記詞的訊息
按照下面給出的順序寫下這 12 個單詞,並將它們存放在安全秘密的地方。
您的助記詞
@@ -210,13 +205,8 @@
那麼,讓我們檢查一下
要開始,只需將 wxDAI 獲取到您的錢包
這會花上幾秒
- 請查看Email已獲得更多指示
- 要開始使用您的卡,您必須通過 KYC驗證
- 請等待驗證完成,您將收到電子郵件通知。通常最多需要 1 小時。您可以關閉該應用程序,稍後再回來
要開始備份過程,最多可添加兩張備份卡。
您可以再添加一張卡或完成備份過程
- 設置一個 4 位密碼。 \n它將用在付款時使用。
- 將您的卡片連接到去中心化支付系統
準備編號為 %s 的備份卡
準備主卡
準備編號為 %s 的主卡
@@ -227,13 +217,9 @@
備份卡 #%d
獲取%s
獲取中
- 有東西出錯了
- 確認你的身分
- KYC 認證中
沒有備用卡
添加了一張備用卡
PIN 碼
- 連接你的錢包
準備好你的卡片
添加了兩張備用卡
要開始使用,只需為錢包充值任意金額
@@ -279,12 +265,6 @@
恢復原廠設置將從所選卡中完全刪除錢包並將其從應用程序中刪除。您將無法恢復當前錢包
您有其他國家的銀行卡或銀聯卡嗎?
目前不接受俄羅斯銀行卡
- 輕觸帶有 visa 標誌的卡片
- 注意
- 請聯繫客服
- 沒有激活資金
- 這樣的 PIN 很容易被暴力破解
- 四個相同的數字不安全
登錄應用程序並在不掃描卡片的情況下檢查您的資產
訪問應用程序
允許使用生物辨識
@@ -301,11 +281,7 @@
搜尋代幣
數量
地址
- 地址或 PayString
地址與錢包地址相同
- PayString 未註冊
- PayString 請求失敗
- PayString 不被區塊鏈支持
標籤無效。它不會被添加到交易中
Memo無效。 它不會被添加到交易中
Tag
@@ -317,7 +293,6 @@
優先
最大值
網路費
- 發送
發送 %s
總計
%1$s 和 %2$s 將被發送
@@ -333,6 +308,7 @@
Solana 網絡每 2 天收取 %1$s 的費用。無法付此費用的帳戶將從網絡中清除。向您的帳戶存入超過 %2$s 即可免費使用
安全地存儲您的加密貨幣,同時將私鑰保存在您的卡中
創新式的硬體錢包
+ 最多 **3張實體卡片** 到一個錢包
最多
3張實體卡片
到一個錢包
@@ -415,7 +391,6 @@
單一幣種
我的錢包
用 %s 解鎖全部
- 創建支付字符串
交易記錄
網路無法使用
區塊鍊無法使用。稍後再試
@@ -424,21 +399,26 @@
交易進行中
檢視餘額
動作
- 購買
- 銷售
- 發送
您想要購買或賣出交易貨幣?
請求籤署消息。%s
Dapp %1$s,請求\n簽署 BNB 交易。\n%2$s
%1$s 的交易訂單\n價格: %2$s\n接收金額:%3$s\n支付數量: %4$s
交易明細:\n從: %1$s\n到: %2$s\n數量: %3$s
+ BNB 交易已成功簽署並發送至 Dapp
剪貼板包含 WalletConnect 代碼。使用複制的值或掃描二維碼
請求為 %1$s 創建交易\n%2$s\n\n數量: %3$s\n費用: %4$s\n全部的: %5$s\n餘額: %6$s
無法交易,無足夠資金
未能建立 WalletConnect 連接。請稍後再試
+ 並非所有代幣都已添加到您的列表中。請先添加它們,然後重試。缺少標記:\n
+ 無法簽署消息。請重試
無法建立 WalletConnect 連接:超時錯誤。請稍後再試
- 會話請求包含不支持 WalletConnect 連接的區塊鏈。不支持的區塊鏈:
+ 會話請求包含不支持 WalletConnect 連接的區塊鏈。不支持的區塊鏈:\n
由於技術問題,無法與此 Dapp 建立連接
+ 我們遇到了未知錯誤。錯誤信息:%s。如果問題仍然存在-請隨時聯繫我們的客服人員
+ 在 Tangem App 中選擇了錯誤的卡
+ 無法從 Dapp 數據創建交易。代碼: %s
+ 我們遇到了未知錯誤。錯誤代碼:%d。如果問題仍然存在-請隨時聯繫我們的支持人員
+ 消息已成功簽名並發送至Dapp
沒有 %s 網路,請先加入後再試一次
從剪貼板貼上
請求開始會話\n%1$s\n\n網絡: %2$s\n\n網址:%3$s
@@ -447,8 +427,12 @@
此卡不能用於建立 WalletConnect 連接
不支持此網絡。請選擇其他網絡
選擇網路
+ Dapp 沒有提供必要的數據來建立 WalletConnect 連接
連結到Dapps
WalletConnect
+ 交易已成功簽署並發送至 Dapp
+ 交易已成功簽署並發送至區塊鏈
+ 未能找到交易哈希
%s 網路
帳號尚未被創造
不支持此卡
diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml
index e68fd193bb..cd659ff14e 100644
--- a/core/res/src/main/res/values/strings.xml
+++ b/core/res/src/main/res/values/strings.xml
@@ -50,27 +50,42 @@
Balance: %s
biometric authentication
biometrics
+ Buy
You have not given access to your camera, please adjust your privacy settings
Cancel
Close
Copy
+ Copy address
Create
Delete
Disabled
+ Dislike
Done
Enable
Enabled
+ Exchange
+ Explore transaction history
Explorer
+ Learn & Earn
+ Like
+ Main network
No
+ No data
OK
Primary Card
+ Receive
Reject
+ Reload
Save changes
Search
+ Seed phrase
+ Sell
+ Send
The server is not available, please try again later
Share
Sign
Sign and send
+ Stake
Start
Submit
Success
@@ -79,6 +94,7 @@
Transactions
Transfer
I understand
+ Unreachable
Yes
Contract address copied!
Available networks
@@ -143,11 +159,18 @@
Tap the card
Internal error: wallet manager not found
You have updated biometrics, scan your card to enter
+ You have completed all of the lessons, and are now eligible to receive your 1INCH tokens
+
+ - Complete three lessons and receive %d 1INCH token to your wallet
+ - Complete three lessons and receive %d 1INCH tokens to your wallet
+
Manage tokens
To protect your assets, we advise you to carry out this procedure
Your wallet has not been backed up
Total balance
The amount does not include some of your funds
+ 1INCH tokens will be credited to your %s wallet address within 24 hours
+ There was no purchase of a wallet using your promo code, which means you cannot receive a bonus. Buy Tangem wallet, scan it in the app, and get the bonus.
To access all the networks you need to scan the card
Scan your card
You have to set up a single access code to protect all your wallets
@@ -171,11 +194,8 @@
Claim
Continue to my wallet
Finalize the backup
- Verify via Utorg
- Refresh
Set PIN code
Receive crypto
- Register
Scan primary card
Skip for later
How does it work?
@@ -191,18 +211,9 @@
Do you want to exit the activation process?
Getting started
Another wallet has already been created on the card you\'re trying to add. Do you want to reset it and use the card for a new wallet?
- Verify your identity
- KYC
Pin code
Connect
Creating a backup
- Tap the SaltPay card
- To start the backup process you have to add the Tangem card as your backup
- Finalize the backup process by creating an access code
- Tap the Tangem card
- No backup card
- Backup card ready
- Prepare the SaltPay card
Read more about seed phrases
Write these 12 words down in the order given below and store them in a safe and secret place.
Your secret phrase
@@ -218,13 +229,8 @@
So, let’s check
To get started, simply claim wxDAI to your wallet
It will take a few seconds
- Please check your email for further instructions
- To start using your card you have to pass the KYC process
- Please wait until the verification is completed. You\'ll be notified via email. Usually it takes up to 1 hour. You can close the app and come back later.
To start the backup process add up to two backup cards.
You can add one more card or finalize the backup process
- Set up a 4-digit code.\nIt will be used for payments.
- Connect your card to the decentralized payment system
Prepare the backup card with number %s
Prepare the primary card
Prepare the primary card with number %s
@@ -235,13 +241,9 @@
Backup card #%d
Claim %s
Claiming
- Something went wrong
- Verify your identity
- KYC is in progress
No backup cards
One backup card added
PIN Code
- Connect your card
Prepare your card
Two backup cards added
To get started, simply top up the wallet with any amount
@@ -262,6 +264,10 @@
Group
By balance
Organize tokens
+ Ungroup
+ %1$s %2$s address on %3$s network
+ %1$s (%2$s) on %3$s network
+ Send only %s to this address. Sending any other currency will result in its irreversible loss.
Participate
Failed to load the information about the referral program. Please try again later.
Failed to load the information about the referral program. Error code: %s. Please try again later.
@@ -291,12 +297,6 @@
Factory Reset will completely delete the wallet from the selected card and remove it from the app. You will not be able to restore the current wallet.
Do you have a bank card of another country or a UnionPay card?
Russian bank cards are not accepted at the moment
- Tap the card with the visa logo
- Attention
- Please contact support
- No funds for activation
- Such a PIN can be brute-forced easily
- Four identical digits isn\'t safe
Log into the app and check your balance without scanning the card
Access the app
Allow to use biometrics
@@ -313,11 +313,7 @@
Search tokens
Amount
Address
- Address or PayString
Address is the same as wallet address
- PayString not registered
- PayString request failed
- PayString unsupported by blockchain
Invalid Tag. It won\'t be added to the transaction.
Invalid Memo. It won\'t be added to the transaction.
Tag
@@ -329,7 +325,6 @@
Priority
Maximum amount
Network fee
- Send
Sending %s
Total
%1$s and %2$s will be sent
@@ -346,6 +341,7 @@
Solana network charges a rent of %1$s every 2 days. Accounts that can\'t afford the rent are purged from the network. Deposit your account with more than %2$s to use it for free.
Store your crypto assets secure while keeping private keys contained in your card
Revolutionary Hardware Wallet
+ Up to **3 physical cards** to one wallet
Up to
3 physical cards
to one wallet
@@ -354,6 +350,8 @@
Thousands of Currencies
Use it on the go, anywhere, anytime. No wires or batteries. Just tap the card to your phone when you need your crypto.
The Wallet for Everyone
+ Take three lessons, get a discount on your Tangem Wallet, and receive 1INCH tokens to your wallet
+ Learn
Borrow
Buy
Exchange
@@ -404,6 +402,7 @@
Hide token
%1$s is a token in the %2$s network. To make a %3$s transaction you need to deposit some %4$s (%5$s) to cover the network fee.
Please wait for %s transaction to complete to be able to send funds
+ %1$s token in %%image%% %2$s network
The %1$s token is the main currency on the %2$s network and cannot be hidden as long as you have other tokens on this network in the list.
Unable to hide %s
No rate
@@ -438,7 +437,6 @@
Single-currency
My Wallets
Unlock all with %s
- Create PayString
Transaction history
Network is unreachable
Blockchain is unreachable. Try later
@@ -447,21 +445,26 @@
Transaction is in progress…
Verified Balance
Actions
- Buy
- Sell
- Send
Do you want to buy or sell crypto?
Requesting to sign a message.\n\n%s
Dapp %1$s, requesting to\nsign BNB transaction.\n\n%2$s
Trade order for %1$s\nPrice: %2$s\nAmount to receive: %3$s\nAmount to pay: %4$s
Transaction details:\nFrom: %1$s\nTo: %2$s\nAmount: %3$s
+ The BNB transaction has been successfully signed and sent to the Dapp
Clipboard contain WalletConnect code. Use copied value or scan QR-code
Request to create transaction for %1$s\n%2$s\n\nAmount: %3$s\nFee: %4$s\nTotal: %5$s\nBalance: %6$s
Can\'t send transaction. Not enough funds.
Failed to establish WalletConnect session. Please, try again later.
+ Not all tokens were added to your list. Please add them first and try again. Missing tokens:\n
+ Failed to sign message.\nPlease, try again
Failed to establish WalletConnect session: timeout error. Please, try again later.
Session request contains unsupported blockchains for WalletConnect connection. Unsupported blockchains:\n
Connection with this Dapp cannot be established due to its technical implementation.
+ We\'ve encountered unknown error. Error message: %s. If the problem persists — feel free to contact our support
+ Wrong card selected in Tangem App
+ Failed to create transaction from Dapp data. Code: %s
+ We\'ve encountered unknown error. Error code: %d. If the problem persists — feel free to contact our support
+ The message has been successfully signed and sent to the Dapp
%s network not found. Please, add it first and try again.
Paste from clipboard
Request to start a session for\n%1$s\n\nNETWORK: %2$s\n\nURL: %3$s
@@ -470,12 +473,18 @@
This card can\'t be used to establish WalletConnect session
This network is not supported. Please select another network.
Select network
+ Dapp didn\'t provide essential data to establish WalletConnect session
Connect to Dapps
WalletConnect
+ The transaction has been successfully signed and sent to the Dapp
+ The transaction has been succesfully signed and sent to the blockchain
+ Failed to find transaction hash
%s network
Account is not created
This card is not supported
Your Tangem card was made to work with a different application. Please see the name and instructions on your card, and install the correct app
+ %s Market Price
+ last 24h
%s network
Address was copied to clipboard
No internet connection
diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/Buttons.kt b/core/ui/src/main/java/com/tangem/core/ui/components/Buttons.kt
index 5ca9a16de8..11682ec1f1 100644
--- a/core/ui/src/main/java/com/tangem/core/ui/components/Buttons.kt
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/Buttons.kt
@@ -2,19 +2,17 @@ package com.tangem.core.ui.components
import androidx.annotation.DrawableRes
import androidx.compose.foundation.background
-import androidx.compose.foundation.layout.*
-import androidx.compose.material.*
-import androidx.compose.runtime.*
-import androidx.compose.ui.Alignment
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.graphics.Shape
-import androidx.compose.ui.res.painterResource
-import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.tooling.preview.Preview
-import androidx.compose.ui.unit.Dp
-import androidx.compose.ui.unit.dp
import com.tangem.core.ui.R
+import com.tangem.core.ui.components.buttons.common.TangemButton
+import com.tangem.core.ui.components.buttons.common.TangemButtonIconPosition
+import com.tangem.core.ui.components.buttons.common.TangemButtonSize
+import com.tangem.core.ui.components.buttons.common.TangemButtonsDefaults
import com.tangem.core.ui.res.TangemTheme
// region TextButton
@@ -26,7 +24,7 @@ fun TextButton(text: String, onClick: () -> Unit, modifier: Modifier = Modifier,
TangemButton(
modifier = modifier,
text = text,
- icon = TangemButtonIcon.None,
+ icon = TangemButtonIconPosition.None,
onClick = onClick,
enabled = enabled,
showProgress = false,
@@ -49,7 +47,7 @@ fun TextButtonIconStart(
TangemButton(
modifier = modifier,
text = text,
- icon = TangemButtonIcon.Start(iconResId),
+ icon = TangemButtonIconPosition.Start(iconResId),
onClick = onClick,
enabled = enabled,
showProgress = false,
@@ -63,7 +61,7 @@ fun WarningTextButton(text: String, onClick: () -> Unit, modifier: Modifier = Mo
TangemButton(
modifier = modifier,
text = text,
- icon = TangemButtonIcon.None,
+ icon = TangemButtonIconPosition.None,
onClick = onClick,
enabled = enabled,
showProgress = false,
@@ -85,7 +83,7 @@ fun PrimaryButton(
TangemButton(
modifier = modifier,
text = text,
- icon = TangemButtonIcon.None,
+ icon = TangemButtonIconPosition.None,
onClick = onClick,
colors = TangemButtonsDefaults.primaryButtonColors,
enabled = enabled,
@@ -108,7 +106,7 @@ fun PrimaryButtonIconEnd(
TangemButton(
modifier = modifier,
text = text,
- icon = TangemButtonIcon.End(iconResId),
+ icon = TangemButtonIconPosition.End(iconResId),
onClick = onClick,
colors = TangemButtonsDefaults.primaryButtonColors,
enabled = enabled,
@@ -131,7 +129,7 @@ fun PrimaryButtonIconStart(
TangemButton(
modifier = modifier,
text = text,
- icon = TangemButtonIcon.Start(iconResId),
+ icon = TangemButtonIconPosition.Start(iconResId),
onClick = onClick,
colors = TangemButtonsDefaults.primaryButtonColors,
enabled = enabled,
@@ -152,7 +150,7 @@ fun SecondaryButton(
TangemButton(
modifier = modifier,
text = text,
- icon = TangemButtonIcon.None,
+ icon = TangemButtonIconPosition.None,
onClick = onClick,
colors = TangemButtonsDefaults.secondaryButtonColors,
enabled = enabled,
@@ -175,7 +173,7 @@ fun SecondaryButtonIconEnd(
TangemButton(
modifier = modifier,
text = text,
- icon = TangemButtonIcon.End(iconResId),
+ icon = TangemButtonIconPosition.End(iconResId),
onClick = onClick,
colors = TangemButtonsDefaults.secondaryButtonColors,
enabled = enabled,
@@ -198,7 +196,7 @@ fun SecondaryButtonIconStart(
TangemButton(
modifier = modifier,
text = text,
- icon = TangemButtonIcon.Start(iconResId),
+ icon = TangemButtonIconPosition.Start(iconResId),
onClick = onClick,
colors = TangemButtonsDefaults.secondaryButtonColors,
enabled = enabled,
@@ -214,7 +212,7 @@ fun SelectorButton(text: String, onClick: () -> Unit, modifier: Modifier = Modif
modifier = modifier,
text = text,
textStyle = TangemTheme.typography.subtitle2,
- icon = TangemButtonIcon.End(iconResId = R.drawable.ic_chevron_24),
+ icon = TangemButtonIconPosition.End(iconResId = R.drawable.ic_chevron_24),
onClick = onClick,
colors = TangemButtonsDefaults.selectorButtonColors,
showProgress = false,
@@ -224,362 +222,6 @@ fun SelectorButton(text: String, onClick: () -> Unit, modifier: Modifier = Modif
}
// endregion Other
-// region Action
-
-/**
- * [Show in Figma](https://www.figma.com/file/14ISV23YB1yVW1uNVwqrKv/Android?type=design&node-id=290-305&t=3z98eFnTeyIx5TH5-4)
- * */
-@Composable
-fun RoundedActionButton(
- text: String,
- @DrawableRes iconResId: Int,
- onClick: () -> Unit,
- modifier: Modifier = Modifier,
- enabled: Boolean = true,
-) {
- TangemButton(
- modifier = modifier,
- text = text,
- icon = TangemButtonIcon.Start(iconResId),
- onClick = onClick,
- enabled = enabled,
- showProgress = false,
- colors = TangemButtonsDefaults.secondaryButtonColors,
- size = TangemButtonSize.RoundedAction,
- )
-}
-
-/**
- * [Show in Figma](https://www.figma.com/file/14ISV23YB1yVW1uNVwqrKv/Android?type=design&node-id=1208-1395&t=3z98eFnTeyIx5TH5-4)
- * */
-@Composable
-fun ActionButton(
- text: String,
- @DrawableRes iconResId: Int,
- onClick: () -> Unit,
- modifier: Modifier = Modifier,
- enabled: Boolean = true,
-) {
- TangemButton(
- modifier = modifier,
- text = text,
- icon = TangemButtonIcon.Start(iconResId),
- onClick = onClick,
- enabled = enabled,
- showProgress = false,
- colors = TangemButtonsDefaults.secondaryButtonColors,
- size = TangemButtonSize.Action,
- )
-}
-
-/**
- * Same as [RoundedActionButton] but colored in primary background color
- * */
-@Composable
-fun BackgroundActionButton(
- text: String,
- @DrawableRes iconResId: Int,
- onClick: () -> Unit,
- modifier: Modifier = Modifier,
- enabled: Boolean = true,
-) {
- TangemButton(
- modifier = modifier,
- text = text,
- icon = TangemButtonIcon.Start(iconResId),
- onClick = onClick,
- enabled = enabled,
- showProgress = false,
- colors = TangemButtonsDefaults.backgroundButtonColors,
- size = TangemButtonSize.RoundedAction,
- )
-}
-// endregion Action
-
-// region Defaults
-@Suppress("LongParameterList")
-@Composable
-private fun TangemButton(
- text: String,
- icon: TangemButtonIcon,
- onClick: () -> Unit,
- colors: ButtonColors,
- showProgress: Boolean,
- enabled: Boolean,
- modifier: Modifier = Modifier,
- size: TangemButtonSize = TangemButtonSize.Default,
- elevation: ButtonElevation = TangemButtonsDefaults.elevation,
- textStyle: TextStyle = TangemTheme.typography.button,
-) {
- Button(
- modifier = modifier.heightIn(min = size.toHeightDp()),
- onClick = { if (!showProgress) onClick() },
- enabled = enabled,
- elevation = elevation,
- shape = size.toShape(),
- colors = colors,
- contentPadding = size.toContentPadding(icon = icon),
- ) {
- ButtonContent(
- text = text,
- textStyle = textStyle,
- buttonIcon = icon,
- colors = colors,
- showProgress = showProgress,
- enabled = enabled,
- size = size,
- )
- }
-}
-
-@Suppress("LongParameterList")
-@Composable
-private fun ButtonContent(
- text: String,
- textStyle: TextStyle,
- buttonIcon: TangemButtonIcon,
- colors: ButtonColors,
- size: TangemButtonSize,
- enabled: Boolean,
- showProgress: Boolean,
-) {
- val icon = @Composable { iconResId: Int ->
- Icon(
- modifier = Modifier.size(TangemTheme.dimens.size20),
- painter = painterResource(id = iconResId),
- tint = colors.contentColor(enabled = enabled).value,
- contentDescription = null,
- )
- }
-
- if (showProgress) {
- Box(modifier = Modifier.wrapContentSize()) {
- CircularProgressIndicator(
- modifier = Modifier
- .align(Alignment.Center)
- .size(TangemTheme.dimens.size24),
- color = colors.contentColor(enabled = enabled).value,
- strokeWidth = TangemTheme.dimens.size4,
- )
- }
- } else {
- Row(
- verticalAlignment = Alignment.CenterVertically,
- horizontalArrangement = Arrangement.spacedBy(size.toIconPadding()),
- ) {
- if (buttonIcon is TangemButtonIcon.Start) {
- icon(buttonIcon.iconResId)
- }
- Text(
- text = text,
- style = textStyle,
- color = colors.contentColor(enabled = enabled).value,
- maxLines = 1,
- )
- if (buttonIcon is TangemButtonIcon.End) {
- icon(buttonIcon.iconResId)
- }
- }
- }
-}
-
-@Immutable
-private sealed interface TangemButtonIcon {
- val iconResId: Int?
-
- data class Start(override val iconResId: Int) : TangemButtonIcon
-
- data class End(override val iconResId: Int) : TangemButtonIcon
-
- object None : TangemButtonIcon {
- override val iconResId: Int? = null
- }
-}
-
-private enum class TangemButtonSize {
- Default,
- Text,
- Selector,
- Action,
- RoundedAction,
-}
-
-@Composable
-@ReadOnlyComposable
-private fun TangemButtonSize.toHeightDp(): Dp = when (this) {
- TangemButtonSize.Default -> TangemTheme.dimens.size48
- TangemButtonSize.Text -> TangemTheme.dimens.size40
- TangemButtonSize.Selector -> TangemTheme.dimens.size24
- TangemButtonSize.Action,
- TangemButtonSize.RoundedAction,
- -> TangemTheme.dimens.size36
-}
-
-@Composable
-@ReadOnlyComposable
-private fun TangemButtonSize.toShape(): Shape = when (this) {
- TangemButtonSize.Default -> TangemTheme.shapes.roundedCornersMedium
- TangemButtonSize.Text -> TangemTheme.shapes.roundedCornersSmall
- TangemButtonSize.Selector -> TangemTheme.shapes.roundedCornersSmall
- TangemButtonSize.Action -> TangemTheme.shapes.roundedCornersMedium
- TangemButtonSize.RoundedAction -> TangemTheme.shapes.roundedCornersLarge
-}
-
-@Composable
-@ReadOnlyComposable
-private fun TangemButtonSize.toIconPadding(): Dp = when (this) {
- TangemButtonSize.Default -> TangemTheme.dimens.spacing8
- TangemButtonSize.Text -> TangemTheme.dimens.spacing8
- TangemButtonSize.Selector -> 0.dp
- TangemButtonSize.Action,
- TangemButtonSize.RoundedAction,
- -> TangemTheme.dimens.spacing8
-}
-
-@Composable
-@ReadOnlyComposable
-private fun TangemButtonSize.toContentPadding(icon: TangemButtonIcon): PaddingValues {
- val horizontalPadding = this.toHorizontalContentPadding(icon = icon)
-
- return when (this) {
- TangemButtonSize.Default -> PaddingValues(
- top = TangemTheme.dimens.spacing14,
- bottom = TangemTheme.dimens.spacing14,
- start = horizontalPadding.first,
- end = horizontalPadding.second,
- )
- TangemButtonSize.Text -> PaddingValues(
- top = TangemTheme.dimens.spacing10,
- bottom = TangemTheme.dimens.spacing10,
- start = horizontalPadding.first,
- end = horizontalPadding.second,
- )
- TangemButtonSize.Selector -> PaddingValues(
- top = TangemTheme.dimens.spacing0_5,
- bottom = TangemTheme.dimens.spacing0_5,
- start = horizontalPadding.first,
- end = horizontalPadding.second,
- )
- TangemButtonSize.Action,
- TangemButtonSize.RoundedAction,
- -> PaddingValues(
- top = TangemTheme.dimens.spacing8,
- bottom = TangemTheme.dimens.spacing8,
- start = horizontalPadding.first,
- end = horizontalPadding.second,
- )
- }
-}
-
-@Composable
-@ReadOnlyComposable
-private fun TangemButtonSize.toHorizontalContentPadding(icon: TangemButtonIcon): Pair {
- return when (this) {
- TangemButtonSize.Default -> TangemTheme.dimens.spacing32 to TangemTheme.dimens.spacing32
- TangemButtonSize.Text -> when (icon) {
- is TangemButtonIcon.None -> TangemTheme.dimens.spacing16 to TangemTheme.dimens.spacing16
- is TangemButtonIcon.Start -> TangemTheme.dimens.spacing14 to TangemTheme.dimens.spacing16
- is TangemButtonIcon.End -> TangemTheme.dimens.spacing16 to TangemTheme.dimens.spacing14
- }
- TangemButtonSize.Selector -> TangemTheme.dimens.spacing0_5 to TangemTheme.dimens.spacing0_5
- TangemButtonSize.Action,
- TangemButtonSize.RoundedAction,
- -> when (icon) {
- is TangemButtonIcon.None -> TangemTheme.dimens.spacing24 to TangemTheme.dimens.spacing24
- is TangemButtonIcon.Start -> TangemTheme.dimens.spacing16 to TangemTheme.dimens.spacing24
- is TangemButtonIcon.End -> TangemTheme.dimens.spacing24 to TangemTheme.dimens.spacing16
- }
- }
-}
-
-private object TangemButtonsDefaults {
- val elevation: ButtonElevation
- @Composable get() = ButtonDefaults
- .elevation(
- defaultElevation = TangemTheme.dimens.elevation0,
- pressedElevation = TangemTheme.dimens.elevation0,
- )
-
- val primaryButtonColors: ButtonColors
- @Composable
- @ReadOnlyComposable
- get() = TangemButtonColors(
- backgroundColor = TangemTheme.colors.button.primary,
- contentColor = TangemTheme.colors.text.primary2,
- disabledBackgroundColor = TangemTheme.colors.button.disabled,
- disabledContentColor = TangemTheme.colors.text.disabled,
- )
-
- val secondaryButtonColors: ButtonColors
- @Composable
- @ReadOnlyComposable
- get() = TangemButtonColors(
- backgroundColor = TangemTheme.colors.button.secondary,
- contentColor = TangemTheme.colors.text.primary1,
- disabledBackgroundColor = TangemTheme.colors.button.disabled,
- disabledContentColor = TangemTheme.colors.text.disabled,
- )
-
- val defaultTextButtonColors: ButtonColors
- @Composable
- @ReadOnlyComposable
- get() = TangemButtonColors(
- backgroundColor = Color.Transparent,
- contentColor = TangemTheme.colors.text.secondary,
- disabledBackgroundColor = Color.Transparent,
- disabledContentColor = TangemTheme.colors.text.disabled,
- )
-
- val warningTextButtonColors: ButtonColors
- @Composable
- @ReadOnlyComposable
- get() = TangemButtonColors(
- backgroundColor = Color.Transparent,
- contentColor = TangemTheme.colors.text.warning,
- disabledBackgroundColor = Color.Transparent,
- disabledContentColor = TangemTheme.colors.text.disabled,
- )
-
- val selectorButtonColors: ButtonColors
- @Composable
- @ReadOnlyComposable
- get() = TangemButtonColors(
- backgroundColor = Color.Transparent,
- contentColor = TangemTheme.colors.text.tertiary,
- disabledBackgroundColor = Color.Transparent,
- disabledContentColor = TangemTheme.colors.text.disabled,
- )
-
- val backgroundButtonColors: ButtonColors
- @Composable
- @ReadOnlyComposable
- get() = TangemButtonColors(
- backgroundColor = TangemTheme.colors.background.primary,
- contentColor = TangemTheme.colors.text.primary1,
- disabledBackgroundColor = TangemTheme.colors.button.disabled,
- disabledContentColor = TangemTheme.colors.text.disabled,
- )
-}
-
-@Immutable
-private open class TangemButtonColors(
- private val backgroundColor: Color,
- private val contentColor: Color,
- private val disabledBackgroundColor: Color,
- private val disabledContentColor: Color,
-) : ButtonColors {
- @Composable
- override fun backgroundColor(enabled: Boolean): State {
- return rememberUpdatedState(newValue = if (enabled) backgroundColor else disabledBackgroundColor)
- }
-
- @Composable
- override fun contentColor(enabled: Boolean): State {
- return rememberUpdatedState(newValue = if (enabled) contentColor else disabledContentColor)
- }
-}
-// endregion Defaults
-
// region Preview
@Composable
private fun PrimaryButtonSample() {
@@ -730,34 +372,4 @@ private fun TextButtonPreview_DarkTheme() {
}
}
-@Composable
-private fun ActionButtonSample() {
- Column(
- modifier = Modifier.background(TangemTheme.colors.background.primary),
- verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8),
- ) {
- RoundedActionButton(text = "Send", iconResId = R.drawable.ic_arrow_up_24, onClick = { })
- ActionButton(text = "Send", iconResId = R.drawable.ic_arrow_up_24, onClick = { })
- BackgroundActionButton(text = "Send", iconResId = R.drawable.ic_arrow_up_24, onClick = { })
- RoundedActionButton(text = "Send", iconResId = R.drawable.ic_arrow_up_24, enabled = false, onClick = { })
- ActionButton(text = "Send", iconResId = R.drawable.ic_arrow_up_24, enabled = false, onClick = { })
- BackgroundActionButton(text = "Send", iconResId = R.drawable.ic_arrow_up_24, enabled = false, onClick = { })
- }
-}
-
-@Preview(showBackground = true, widthDp = 360)
-@Composable
-private fun ActionButtonPreview_LightTheme() {
- TangemTheme {
- ActionButtonSample()
- }
-}
-
-@Preview(showBackground = true, widthDp = 360)
-@Composable
-private fun ActionButtonPreview_DarkTheme() {
- TangemTheme(isDark = true) {
- ActionButtonSample()
- }
-}
// endregion Preview
\ No newline at end of file
diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/Notifications.kt b/core/ui/src/main/java/com/tangem/core/ui/components/Notifications.kt
deleted file mode 100644
index e70f571b18..0000000000
--- a/core/ui/src/main/java/com/tangem/core/ui/components/Notifications.kt
+++ /dev/null
@@ -1,202 +0,0 @@
-package com.tangem.core.ui.components
-
-import androidx.annotation.DrawableRes
-import androidx.compose.foundation.Image
-import androidx.compose.foundation.clickable
-import androidx.compose.foundation.layout.*
-import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.material.*
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.res.painterResource
-import androidx.compose.ui.tooling.preview.Preview
-import com.tangem.core.ui.R
-import com.tangem.core.ui.res.TangemTheme
-
-/**
- * Closable notification with custom icon
- * Child of parent component
- * @see Figma component
- *
- * Use to show banner with custom icon and possibility to close
- * i.e. Feedback notification
- *
- * @param title notification title
- * @param icon drawable res on icon
- * @param iconColor icon color
- * @param onClick callback on click
- * @param onCloseClick callback on close icon click
- */
-@Composable
-fun ClosableNotification(
- title: String,
- @DrawableRes icon: Int,
- iconColor: Color,
- onClick: (() -> Unit),
- onCloseClick: (() -> Unit),
-) {
- NotificationCardTemplate(onClick) {
- Icon(
- modifier = Modifier
- .size(TangemTheme.dimens.size20)
- .align(Alignment.CenterStart),
- painter = painterResource(id = icon),
- tint = iconColor,
- contentDescription = null,
- )
- Text(
- modifier = Modifier
- .padding(horizontal = TangemTheme.dimens.spacing28)
- .align(Alignment.CenterStart),
- text = title,
- color = TangemTheme.colors.text.primary1,
- style = TangemTheme.typography.subtitle2,
- )
- Icon(
- modifier = Modifier
- .size(TangemTheme.dimens.size20)
- .align(Alignment.CenterEnd)
- .clickable(onClick = onCloseClick),
- painter = painterResource(id = R.drawable.ic_close_24),
- contentDescription = null,
- tint = TangemTheme.colors.icon.informative,
- )
- }
-}
-
-/**
- * Notification component from Design system
- * There are few states for this component, but only one parent, see link below
- *
- * Use this for Notification with title, subtitle, clickable or not
- *
- * @param title notification title
- * @param subtitle notification subtitle
- * @param onClick click on notification, if its null then no chevron icon
- *
- * @see Figma component
- */
-@Composable
-fun WarningNotification(title: String, subtitle: String?, onClick: (() -> Unit)?) {
- NotificationCardTemplate(onClick) {
- Image(
- modifier = Modifier
- .size(TangemTheme.dimens.size20)
- .align(Alignment.CenterStart),
- painter = painterResource(id = R.drawable.img_attention_20),
- contentDescription = null,
- )
- Column(
- modifier = Modifier
- .padding(horizontal = TangemTheme.dimens.spacing28)
- .align(Alignment.CenterStart),
- ) {
- Text(
- text = title,
- color = TangemTheme.colors.text.primary1,
- style = TangemTheme.typography.subtitle2,
- )
- if (!subtitle.isNullOrEmpty()) {
- SpacerH2()
- Text(
- text = subtitle,
- color = TangemTheme.colors.text.tertiary,
- style = TangemTheme.typography.caption,
- )
- }
- }
- if (onClick != null) {
- Icon(
- modifier = Modifier
- .size(TangemTheme.dimens.size20)
- .align(Alignment.CenterEnd),
- painter = painterResource(id = R.drawable.ic_chevron_right_24),
- contentDescription = null,
- tint = TangemTheme.colors.icon.informative,
- )
- }
- }
-}
-
-@OptIn(ExperimentalMaterialApi::class)
-@Composable
-private fun NotificationCardTemplate(onClick: (() -> Unit)? = null, content: @Composable BoxScope.() -> Unit) {
- Surface(
- color = TangemTheme.colors.button.secondary,
- shape = RoundedCornerShape(TangemTheme.dimens.radius18),
- onClick = onClick ?: {},
- enabled = onClick != null,
- ) {
- Box(
- Modifier
- .padding(
- horizontal = TangemTheme.dimens.spacing12,
- vertical = TangemTheme.dimens.spacing8,
- )
- .wrapContentSize(),
- ) {
- content()
- }
- }
-}
-
-// region Preview
-
-@Composable
-private fun WarningNotificationPreview() {
- Column(modifier = Modifier.fillMaxWidth()) {
- WarningNotification(
- title = "Your wallet hasn’t been backed up",
- subtitle = "Lorem ipsum dolor sit amet, consectetur " +
- "adipiscing elit, sed do eiusmod tempor incididunt ut labore et...",
- onClick = {},
- )
- SpacerH32()
- WarningNotification(
- title = "Your wallet hasn’t been backed up",
- subtitle = null,
- onClick = {},
- )
- SpacerH32()
- WarningNotification(
- title = "Your wallet hasn’t been backed up",
- subtitle = "Lorem ipsum dolor sit amet, consectetur " +
- "adipiscing elit, sed do eiusmod tempor incididunt ut labore et...",
- onClick = null,
- )
- SpacerH32()
- WarningNotification(
- title = "Your wallet hasn’t been backed up",
- subtitle = null,
- onClick = null,
- )
- SpacerH32()
- ClosableNotification(
- title = "Like tangem app?",
- icon = R.drawable.ic_star_24,
- iconColor = TangemTheme.colors.icon.attention,
- onClick = {},
- onCloseClick = {},
- )
- }
-}
-
-@Preview(showBackground = true)
-@Composable
-private fun Preview_WarningNotification_InLightTheme() {
- TangemTheme(isDark = false) {
- WarningNotificationPreview()
- }
-}
-
-@Preview(showBackground = true)
-@Composable
-private fun Preview_WarningNotification_InDarkTheme() {
- TangemTheme(isDark = true) {
- WarningNotificationPreview()
- }
-}
-
-// endregion Preview
\ No newline at end of file
diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/buttons/actions/ActionButtonConfig.kt b/core/ui/src/main/java/com/tangem/core/ui/components/buttons/actions/ActionButtonConfig.kt
new file mode 100644
index 0000000000..3e69942c7f
--- /dev/null
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/buttons/actions/ActionButtonConfig.kt
@@ -0,0 +1,20 @@
+package com.tangem.core.ui.components.buttons.actions
+
+import androidx.annotation.DrawableRes
+
+/**
+ * Action button config
+ *
+ * @property text text
+ * @property iconResId icon resource id
+ * @property onClick lambda be invoked when action component is clicked
+ * @property enabled enabled
+ *
+[REDACTED_AUTHOR]
+ */
+data class ActionButtonConfig(
+ val text: String,
+ @DrawableRes val iconResId: Int,
+ val onClick: () -> Unit,
+ val enabled: Boolean = true,
+)
\ No newline at end of file
diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/buttons/actions/Actions.kt b/core/ui/src/main/java/com/tangem/core/ui/components/buttons/actions/Actions.kt
new file mode 100644
index 0000000000..068172b71e
--- /dev/null
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/buttons/actions/Actions.kt
@@ -0,0 +1,152 @@
+package com.tangem.core.ui.components.buttons.actions
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.Icon
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.tooling.preview.PreviewParameter
+import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
+import com.tangem.core.ui.R
+import com.tangem.core.ui.components.SpacerW8
+import com.tangem.core.ui.components.buttons.common.*
+import com.tangem.core.ui.res.TangemTheme
+
+/**
+ * Rounded action button
+ *
+ * @param config component config
+ * @param modifier modifier
+ * @param color background color
+ *
+ * @see Show in Figma
+ */
+@Composable
+fun RoundedActionButton(
+ config: ActionButtonConfig,
+ modifier: Modifier = Modifier,
+ color: Color = TangemTheme.colors.button.secondary,
+) {
+ Button(
+ config = config,
+ shape = RoundedCornerShape(size = TangemTheme.dimens.radius24),
+ modifier = modifier,
+ color = color,
+ )
+}
+
+/**
+ * Action button
+ *
+ * @param config component config
+ * @param modifier modifier
+ * @param color background color
+ *
+ * @see Show in Figma
+ */
+@Composable
+fun ActionButton(
+ config: ActionButtonConfig,
+ modifier: Modifier = Modifier,
+ color: Color = TangemTheme.colors.button.secondary,
+) {
+ Button(
+ config = config,
+ shape = RoundedCornerShape(size = TangemTheme.dimens.radius12),
+ modifier = modifier,
+ color = color,
+ )
+}
+
+@Composable
+private fun Button(
+ config: ActionButtonConfig,
+ shape: RoundedCornerShape,
+ modifier: Modifier = Modifier,
+ color: Color = TangemTheme.colors.button.secondary,
+) {
+ Row(
+ modifier = modifier
+ .heightIn(min = TangemTheme.dimens.size36)
+ .clip(shape)
+ .background(
+ color = if (config.enabled) color else TangemTheme.colors.button.disabled,
+ shape = shape,
+ )
+ .clickable(enabled = config.enabled, onClick = config.onClick)
+ .padding(
+ start = TangemTheme.dimens.spacing16,
+ end = TangemTheme.dimens.spacing24,
+ )
+ .padding(vertical = TangemTheme.dimens.spacing8),
+ horizontalArrangement = Arrangement.Center,
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ Icon(
+ painter = painterResource(id = config.iconResId),
+ contentDescription = null,
+ modifier = Modifier.size(size = TangemTheme.dimens.size20),
+ tint = if (config.enabled) TangemTheme.colors.icon.primary1 else TangemTheme.colors.icon.informative,
+ )
+
+ SpacerW8()
+
+ Text(
+ text = config.text,
+ color = if (config.enabled) TangemTheme.colors.text.primary1 else TangemTheme.colors.text.disabled,
+ overflow = TextOverflow.Ellipsis,
+ maxLines = 1,
+ style = TangemTheme.typography.button,
+ )
+ }
+}
+
+@Preview(group = "RoundedActionButton", showBackground = true)
+@Composable
+private fun Preview_RoundedActionButton_Light(@PreviewParameter(ActionStateProvider::class) state: ActionButtonConfig) {
+ TangemTheme(isDark = false) {
+ RoundedActionButton(state)
+ }
+}
+
+@Preview(group = "RoundedActionButton", showBackground = true)
+@Composable
+private fun Preview_RoundedActionButton_Dark(@PreviewParameter(ActionStateProvider::class) state: ActionButtonConfig) {
+ TangemTheme(isDark = true) {
+ RoundedActionButton(state)
+ }
+}
+
+@Preview(group = "ActionButton", showBackground = true)
+@Composable
+private fun Preview_ActionButton_Light(@PreviewParameter(ActionStateProvider::class) state: ActionButtonConfig) {
+ TangemTheme(isDark = false) {
+ ActionButton(state)
+ }
+}
+
+@Preview(group = "ActionButton", showBackground = true)
+@Composable
+private fun Preview_ActionButton_Dark(@PreviewParameter(ActionStateProvider::class) state: ActionButtonConfig) {
+ TangemTheme(isDark = true) {
+ ActionButton(state)
+ }
+}
+
+private class ActionStateProvider : CollectionPreviewParameterProvider(
+ collection = listOf(
+ ActionButtonConfig(text = "Enabled", iconResId = R.drawable.ic_arrow_up_24, enabled = true, onClick = {}),
+ ActionButtonConfig(text = "Disabled", iconResId = R.drawable.ic_arrow_down_24, enabled = false, onClick = {}),
+ ),
+)
\ No newline at end of file
diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/buttons/common/TangemButton.kt b/core/ui/src/main/java/com/tangem/core/ui/components/buttons/common/TangemButton.kt
new file mode 100644
index 0000000000..b0a5b59116
--- /dev/null
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/buttons/common/TangemButton.kt
@@ -0,0 +1,96 @@
+package com.tangem.core.ui.components.buttons.common
+
+import androidx.compose.foundation.layout.*
+import androidx.compose.material.*
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.text.TextStyle
+import com.tangem.core.ui.res.TangemTheme
+
+@Suppress("LongParameterList")
+@Composable
+internal fun TangemButton(
+ text: String,
+ icon: TangemButtonIconPosition,
+ onClick: () -> Unit,
+ colors: ButtonColors,
+ showProgress: Boolean,
+ enabled: Boolean,
+ modifier: Modifier = Modifier,
+ size: TangemButtonSize = TangemButtonSize.Default,
+ elevation: ButtonElevation = TangemButtonsDefaults.elevation,
+ textStyle: TextStyle = TangemTheme.typography.button,
+) {
+ Button(
+ modifier = modifier.heightIn(min = size.toHeightDp()),
+ onClick = { if (!showProgress) onClick() },
+ enabled = enabled,
+ elevation = elevation,
+ shape = size.toShape(),
+ colors = colors,
+ contentPadding = size.toContentPadding(icon = icon),
+ ) {
+ ButtonContent(
+ text = text,
+ textStyle = textStyle,
+ buttonIcon = icon,
+ colors = colors,
+ showProgress = showProgress,
+ enabled = enabled,
+ size = size,
+ )
+ }
+}
+
+@Suppress("LongParameterList")
+@Composable
+private fun ButtonContent(
+ text: String,
+ textStyle: TextStyle,
+ buttonIcon: TangemButtonIconPosition,
+ colors: ButtonColors,
+ size: TangemButtonSize,
+ enabled: Boolean,
+ showProgress: Boolean,
+) {
+ val icon = @Composable { iconResId: Int ->
+ Icon(
+ modifier = Modifier.size(TangemTheme.dimens.size20),
+ painter = painterResource(id = iconResId),
+ tint = colors.contentColor(enabled = enabled).value,
+ contentDescription = null,
+ )
+ }
+
+ if (showProgress) {
+ Box(modifier = Modifier.wrapContentSize()) {
+ CircularProgressIndicator(
+ modifier = Modifier
+ .align(Alignment.Center)
+ .size(TangemTheme.dimens.size24),
+ color = colors.contentColor(enabled = enabled).value,
+ strokeWidth = TangemTheme.dimens.size4,
+ )
+ }
+ } else {
+ Row(
+ verticalAlignment = Alignment.CenterVertically,
+ horizontalArrangement = Arrangement.spacedBy(size.toIconPadding()),
+ ) {
+ if (buttonIcon is TangemButtonIconPosition.Start) {
+ icon(buttonIcon.iconResId)
+ }
+ Text(
+ text = text,
+ style = textStyle,
+ color = colors.contentColor(enabled = enabled).value,
+ maxLines = 1,
+ )
+ if (buttonIcon is TangemButtonIconPosition.End) {
+ icon(buttonIcon.iconResId)
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/buttons/common/TangemButtonColors.kt b/core/ui/src/main/java/com/tangem/core/ui/components/buttons/common/TangemButtonColors.kt
new file mode 100644
index 0000000000..92a334a139
--- /dev/null
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/buttons/common/TangemButtonColors.kt
@@ -0,0 +1,25 @@
+package com.tangem.core.ui.components.buttons.common
+
+import androidx.compose.material.ButtonColors
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.State
+import androidx.compose.runtime.rememberUpdatedState
+import androidx.compose.ui.graphics.Color
+
+internal class TangemButtonColors(
+ private val backgroundColor: Color,
+ private val contentColor: Color,
+ private val disabledBackgroundColor: Color,
+ private val disabledContentColor: Color,
+) : ButtonColors {
+
+ @Composable
+ override fun backgroundColor(enabled: Boolean): State {
+ return rememberUpdatedState(newValue = if (enabled) backgroundColor else disabledBackgroundColor)
+ }
+
+ @Composable
+ override fun contentColor(enabled: Boolean): State {
+ return rememberUpdatedState(newValue = if (enabled) contentColor else disabledContentColor)
+ }
+}
\ No newline at end of file
diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/buttons/common/TangemButtonIconPosition.kt b/core/ui/src/main/java/com/tangem/core/ui/components/buttons/common/TangemButtonIconPosition.kt
new file mode 100644
index 0000000000..0896e671fb
--- /dev/null
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/buttons/common/TangemButtonIconPosition.kt
@@ -0,0 +1,16 @@
+package com.tangem.core.ui.components.buttons.common
+
+import androidx.annotation.DrawableRes
+
+internal sealed interface TangemButtonIconPosition {
+ val iconResId: Int?
+
+ data class Start(@DrawableRes override val iconResId: Int) : TangemButtonIconPosition
+
+ data class End(@DrawableRes override val iconResId: Int) : TangemButtonIconPosition
+
+ object None : TangemButtonIconPosition {
+ @DrawableRes
+ override val iconResId: Int? = null
+ }
+}
\ No newline at end of file
diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/buttons/common/TangemButtonSize.kt b/core/ui/src/main/java/com/tangem/core/ui/components/buttons/common/TangemButtonSize.kt
new file mode 100644
index 0000000000..6ba9b10d72
--- /dev/null
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/buttons/common/TangemButtonSize.kt
@@ -0,0 +1,105 @@
+package com.tangem.core.ui.components.buttons.common
+
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.ReadOnlyComposable
+import androidx.compose.ui.graphics.Shape
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.dp
+import com.tangem.core.ui.res.TangemTheme
+
+internal enum class TangemButtonSize {
+ Default,
+ Text,
+ Selector,
+ Action,
+ RoundedAction,
+}
+
+@Composable
+@ReadOnlyComposable
+internal fun TangemButtonSize.toHeightDp(): Dp = when (this) {
+ TangemButtonSize.Default -> TangemTheme.dimens.size48
+ TangemButtonSize.Text -> TangemTheme.dimens.size40
+ TangemButtonSize.Selector -> TangemTheme.dimens.size24
+ TangemButtonSize.Action,
+ TangemButtonSize.RoundedAction,
+ -> TangemTheme.dimens.size36
+}
+
+@Composable
+@ReadOnlyComposable
+internal fun TangemButtonSize.toShape(): Shape = when (this) {
+ TangemButtonSize.Default -> TangemTheme.shapes.roundedCornersMedium
+ TangemButtonSize.Text -> TangemTheme.shapes.roundedCornersSmall
+ TangemButtonSize.Selector -> TangemTheme.shapes.roundedCornersSmall
+ TangemButtonSize.Action -> TangemTheme.shapes.roundedCornersMedium
+ TangemButtonSize.RoundedAction -> TangemTheme.shapes.roundedCornersLarge
+}
+
+@Composable
+@ReadOnlyComposable
+internal fun TangemButtonSize.toIconPadding(): Dp = when (this) {
+ TangemButtonSize.Default -> TangemTheme.dimens.spacing8
+ TangemButtonSize.Text -> TangemTheme.dimens.spacing8
+ TangemButtonSize.Selector -> 0.dp
+ TangemButtonSize.Action,
+ TangemButtonSize.RoundedAction,
+ -> TangemTheme.dimens.spacing8
+}
+
+@Composable
+@ReadOnlyComposable
+internal fun TangemButtonSize.toContentPadding(icon: TangemButtonIconPosition): PaddingValues {
+ val horizontalPadding = this.toHorizontalContentPadding(icon = icon)
+
+ return when (this) {
+ TangemButtonSize.Default -> PaddingValues(
+ top = TangemTheme.dimens.spacing14,
+ bottom = TangemTheme.dimens.spacing14,
+ start = horizontalPadding.first,
+ end = horizontalPadding.second,
+ )
+ TangemButtonSize.Text -> PaddingValues(
+ top = TangemTheme.dimens.spacing10,
+ bottom = TangemTheme.dimens.spacing10,
+ start = horizontalPadding.first,
+ end = horizontalPadding.second,
+ )
+ TangemButtonSize.Selector -> PaddingValues(
+ top = TangemTheme.dimens.spacing0_5,
+ bottom = TangemTheme.dimens.spacing0_5,
+ start = horizontalPadding.first,
+ end = horizontalPadding.second,
+ )
+ TangemButtonSize.Action,
+ TangemButtonSize.RoundedAction,
+ -> PaddingValues(
+ top = TangemTheme.dimens.spacing8,
+ bottom = TangemTheme.dimens.spacing8,
+ start = horizontalPadding.first,
+ end = horizontalPadding.second,
+ )
+ }
+}
+
+@Composable
+@ReadOnlyComposable
+internal fun TangemButtonSize.toHorizontalContentPadding(icon: TangemButtonIconPosition): Pair {
+ return when (this) {
+ TangemButtonSize.Default -> TangemTheme.dimens.spacing32 to TangemTheme.dimens.spacing32
+ TangemButtonSize.Text -> when (icon) {
+ is TangemButtonIconPosition.None -> TangemTheme.dimens.spacing16 to TangemTheme.dimens.spacing16
+ is TangemButtonIconPosition.Start -> TangemTheme.dimens.spacing14 to TangemTheme.dimens.spacing16
+ is TangemButtonIconPosition.End -> TangemTheme.dimens.spacing16 to TangemTheme.dimens.spacing14
+ }
+ TangemButtonSize.Selector -> TangemTheme.dimens.spacing0_5 to TangemTheme.dimens.spacing0_5
+ TangemButtonSize.Action,
+ TangemButtonSize.RoundedAction,
+ -> when (icon) {
+ is TangemButtonIconPosition.None -> TangemTheme.dimens.spacing24 to TangemTheme.dimens.spacing24
+ is TangemButtonIconPosition.Start -> TangemTheme.dimens.spacing16 to TangemTheme.dimens.spacing24
+ is TangemButtonIconPosition.End -> TangemTheme.dimens.spacing24 to TangemTheme.dimens.spacing16
+ }
+ }
+}
\ No newline at end of file
diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/buttons/common/TangemButtonsDefaults.kt b/core/ui/src/main/java/com/tangem/core/ui/components/buttons/common/TangemButtonsDefaults.kt
new file mode 100644
index 0000000000..f6c6211dc5
--- /dev/null
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/buttons/common/TangemButtonsDefaults.kt
@@ -0,0 +1,78 @@
+package com.tangem.core.ui.components.buttons.common
+
+import androidx.compose.material.ButtonColors
+import androidx.compose.material.ButtonDefaults
+import androidx.compose.material.ButtonElevation
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.ReadOnlyComposable
+import androidx.compose.ui.graphics.Color
+import com.tangem.core.ui.res.TangemTheme
+
+internal object TangemButtonsDefaults {
+
+ val elevation: ButtonElevation
+ @Composable get() = ButtonDefaults.elevation(
+ defaultElevation = TangemTheme.dimens.elevation0,
+ pressedElevation = TangemTheme.dimens.elevation0,
+ )
+
+ val primaryButtonColors: ButtonColors
+ @Composable
+ @ReadOnlyComposable
+ get() = TangemButtonColors(
+ backgroundColor = TangemTheme.colors.button.primary,
+ contentColor = TangemTheme.colors.text.primary2,
+ disabledBackgroundColor = TangemTheme.colors.button.disabled,
+ disabledContentColor = TangemTheme.colors.text.disabled,
+ )
+
+ val secondaryButtonColors: ButtonColors
+ @Composable
+ @ReadOnlyComposable
+ get() = TangemButtonColors(
+ backgroundColor = TangemTheme.colors.button.secondary,
+ contentColor = TangemTheme.colors.text.primary1,
+ disabledBackgroundColor = TangemTheme.colors.button.disabled,
+ disabledContentColor = TangemTheme.colors.text.disabled,
+ )
+
+ val defaultTextButtonColors: ButtonColors
+ @Composable
+ @ReadOnlyComposable
+ get() = TangemButtonColors(
+ backgroundColor = Color.Transparent,
+ contentColor = TangemTheme.colors.text.secondary,
+ disabledBackgroundColor = Color.Transparent,
+ disabledContentColor = TangemTheme.colors.text.disabled,
+ )
+
+ val warningTextButtonColors: ButtonColors
+ @Composable
+ @ReadOnlyComposable
+ get() = TangemButtonColors(
+ backgroundColor = Color.Transparent,
+ contentColor = TangemTheme.colors.text.warning,
+ disabledBackgroundColor = Color.Transparent,
+ disabledContentColor = TangemTheme.colors.text.disabled,
+ )
+
+ val selectorButtonColors: ButtonColors
+ @Composable
+ @ReadOnlyComposable
+ get() = TangemButtonColors(
+ backgroundColor = Color.Transparent,
+ contentColor = TangemTheme.colors.text.tertiary,
+ disabledBackgroundColor = Color.Transparent,
+ disabledContentColor = TangemTheme.colors.text.disabled,
+ )
+
+ val backgroundButtonColors: ButtonColors
+ @Composable
+ @ReadOnlyComposable
+ get() = TangemButtonColors(
+ backgroundColor = TangemTheme.colors.background.primary,
+ contentColor = TangemTheme.colors.text.primary1,
+ disabledBackgroundColor = TangemTheme.colors.button.disabled,
+ disabledContentColor = TangemTheme.colors.text.disabled,
+ )
+}
\ No newline at end of file
diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/notifications/Notification.kt b/core/ui/src/main/java/com/tangem/core/ui/components/notifications/Notification.kt
new file mode 100644
index 0000000000..9d4f2cf480
--- /dev/null
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/notifications/Notification.kt
@@ -0,0 +1,178 @@
+package com.tangem.core.ui.components.notifications
+
+import androidx.annotation.DrawableRes
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.background
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.Icon
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.tooling.preview.PreviewParameter
+import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
+import com.tangem.core.ui.R
+import com.tangem.core.ui.components.SpacerH2
+import com.tangem.core.ui.res.TangemColorPalette
+import com.tangem.core.ui.res.TangemTheme
+
+/**
+ * Notification component from Design system.
+ * Use this for Notification with title, subtitle, clickable or not.
+ *
+ * @param state component state
+ * @param modifier modifier
+ *
+ * @see Figma component
+ */
+@Composable
+fun Notification(state: NotificationState, modifier: Modifier = Modifier) {
+ Box(
+ modifier = modifier
+ .clip(shape = RoundedCornerShape(size = TangemTheme.dimens.radius18))
+ .background(
+ color = TangemTheme.colors.button.secondary,
+ shape = RoundedCornerShape(size = TangemTheme.dimens.radius18),
+ )
+ .clickable(
+ enabled = when (state) {
+ is NotificationState.Simple -> false
+ is NotificationState.Action -> true
+ },
+ onClick = if (state is NotificationState.Action) {
+ state.onClick
+ } else {
+ {}
+ },
+ ),
+ ) {
+ Box(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(horizontal = TangemTheme.dimens.spacing12, vertical = TangemTheme.dimens.spacing8),
+ ) {
+ NotificationIcon(
+ iconResId = state.iconResId,
+ iconTint = state.tint,
+ modifier = Modifier
+ .size(size = TangemTheme.dimens.size20)
+ .align(alignment = Alignment.CenterStart),
+ )
+
+ NotificationInfoBlock(
+ title = state.title,
+ subtitle = state.subtitle,
+ modifier = Modifier.align(alignment = Alignment.CenterStart),
+ )
+
+ if (state is NotificationState.Action) {
+ Icon(
+ modifier = Modifier
+ .size(size = TangemTheme.dimens.size20)
+ .align(alignment = Alignment.CenterEnd),
+ painter = painterResource(id = R.drawable.ic_chevron_right_24),
+ contentDescription = null,
+ tint = TangemTheme.colors.icon.informative,
+ )
+ }
+ }
+ }
+}
+
+@Composable
+private fun NotificationIcon(@DrawableRes iconResId: Int, iconTint: Color?, modifier: Modifier = Modifier) {
+ if (iconTint != null) {
+ Icon(
+ painter = painterResource(id = iconResId),
+ contentDescription = null,
+ modifier = modifier,
+ tint = iconTint,
+ )
+ } else {
+ Image(
+ painter = painterResource(id = iconResId),
+ contentDescription = null,
+ modifier = modifier,
+ )
+ }
+}
+
+@Composable
+private fun NotificationInfoBlock(title: String, subtitle: String?, modifier: Modifier = Modifier) {
+ Column(modifier = modifier.padding(horizontal = TangemTheme.dimens.spacing30)) {
+ Text(
+ text = title,
+ color = TangemTheme.colors.text.primary1,
+ style = TangemTheme.typography.body2,
+ )
+
+ if (!subtitle.isNullOrEmpty()) {
+ SpacerH2()
+ Text(
+ text = subtitle,
+ color = TangemTheme.colors.text.tertiary,
+ style = TangemTheme.typography.caption,
+ )
+ }
+ }
+}
+
+@Preview
+@Composable
+private fun Preview_WarningNotification_Light(
+ @PreviewParameter(NotificationStateProvider::class)
+ state: NotificationState,
+) {
+ TangemTheme(isDark = false) {
+ Notification(state)
+ }
+}
+
+@Preview
+@Composable
+private fun Preview_WarningNotification_Dark(
+ @PreviewParameter(NotificationStateProvider::class)
+ state: NotificationState,
+) {
+ TangemTheme(isDark = true) {
+ Notification(state)
+ }
+}
+
+private class NotificationStateProvider : CollectionPreviewParameterProvider(
+ collection = listOf(
+ NotificationState.Simple(
+ title = "Your wallet hasn’t been backed up",
+ subtitle = "Lorem ipsum dolor sit amet, consectetur " +
+ "adipiscing elit, sed do eiusmod tempor incididunt ut labore et...",
+ iconResId = R.drawable.img_attention_20,
+ ),
+ NotificationState.Simple(
+ title = "Your wallet hasn’t been backed up",
+ subtitle = null,
+ iconResId = R.drawable.ic_alert_circle_24,
+ tint = TangemColorPalette.Amaranth,
+ ),
+ NotificationState.Action(
+ title = "Your wallet hasn’t been backed up",
+ subtitle = "Lorem ipsum dolor sit amet, consectetur " +
+ "adipiscing elit, sed do eiusmod tempor incididunt ut labore et...",
+ iconResId = R.drawable.img_attention_20,
+ onClick = {},
+ ),
+ NotificationState.Action(
+ title = "Your wallet hasn’t been backed up",
+ subtitle = null,
+ iconResId = R.drawable.ic_alert_circle_24,
+ tint = TangemColorPalette.Amaranth,
+ onClick = {},
+ ),
+ ),
+)
\ No newline at end of file
diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/notifications/NotificationState.kt b/core/ui/src/main/java/com/tangem/core/ui/components/notifications/NotificationState.kt
new file mode 100644
index 0000000000..065fa1e125
--- /dev/null
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/notifications/NotificationState.kt
@@ -0,0 +1,54 @@
+package com.tangem.core.ui.components.notifications
+
+import androidx.annotation.DrawableRes
+import androidx.compose.ui.graphics.Color
+
+/**
+ * Notification component state
+ *
+ * @property title title
+ * @property subtitle subtitle
+ * @property iconResId icon resource id
+ * @property tint icon tint
+ *
+[REDACTED_AUTHOR]
+ */
+sealed class NotificationState(
+ open val title: String,
+ open val subtitle: String? = null,
+ @DrawableRes open val iconResId: Int,
+ open val tint: Color? = null,
+) {
+
+ /**
+ * Simple notification state. Non clickable.
+ *
+ * @property title title
+ * @property subtitle subtitle
+ * @property iconResId icon resource id
+ * @property tint icon tint
+ */
+ data class Simple(
+ override val title: String,
+ override val subtitle: String? = null,
+ @DrawableRes override val iconResId: Int,
+ override val tint: Color? = null,
+ ) : NotificationState(title, subtitle, iconResId, tint)
+
+ /**
+ * Clickable notification state
+ *
+ * @property title title
+ * @property subtitle subtitle
+ * @property iconResId icon resource id
+ * @property tint icon tint
+ * @param onClick lambda be invoked when notification component is clicked
+ */
+ data class Action(
+ override val title: String,
+ override val subtitle: String? = null,
+ @DrawableRes override val iconResId: Int,
+ override val tint: Color? = null,
+ val onClick: () -> Unit,
+ ) : NotificationState(title, subtitle, iconResId, tint)
+}
\ No newline at end of file
diff --git a/core/ui/src/main/java/com/tangem/core/ui/extensions/BlockchainIcons.kt b/core/ui/src/main/java/com/tangem/core/ui/extensions/BlockchainIcons.kt
index f18370422e..c4eeba732a 100644
--- a/core/ui/src/main/java/com/tangem/core/ui/extensions/BlockchainIcons.kt
+++ b/core/ui/src/main/java/com/tangem/core/ui/extensions/BlockchainIcons.kt
@@ -40,6 +40,8 @@ fun getActiveIconRes(blockchainId: String): Int {
"terra", "terra-luna" -> R.drawable.img_terra_22
"terra-2", "terra-luna-2" -> R.drawable.img_terra2_22
"cronos" -> R.drawable.img_cronos_22
+ "TELOS", "TELOS/test" -> R.drawable.img_telos_22
+ "aleph-zero", "aleph-zero/test" -> R.drawable.img_azero_22
else -> R.drawable.ic_alert_24
}
}
@@ -84,6 +86,7 @@ fun getActiveIconResByCoinId(coinId: String, networkId: String): Int {
"ravencoin" -> R.drawable.img_ravencoin_22
"terra" -> R.drawable.img_terra_22
"terra-2" -> R.drawable.img_terra2_22
+ "telos" -> R.drawable.img_telos_22
else -> R.drawable.ic_alert_24
}
}
\ No newline at end of file
diff --git a/core/ui/src/main/java/com/tangem/core/ui/extensions/TextReference.kt b/core/ui/src/main/java/com/tangem/core/ui/extensions/TextReference.kt
index a27dcb58c4..92df3daeb9 100644
--- a/core/ui/src/main/java/com/tangem/core/ui/extensions/TextReference.kt
+++ b/core/ui/src/main/java/com/tangem/core/ui/extensions/TextReference.kt
@@ -1,9 +1,11 @@
package com.tangem.core.ui.extensions
+import androidx.annotation.PluralsRes
import androidx.annotation.StringRes
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.ReadOnlyComposable
+import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.res.stringResource
/**
@@ -24,6 +26,8 @@ sealed interface TextReference {
*/
data class Res(@StringRes val id: Int, val formatArgs: WrappedList = WrappedList(emptyList())) : TextReference
+ data class PluralRes(@PluralsRes val id: Int, val count: Int, val formatArgs: WrappedList) : TextReference
+
/**
* Text string
*
@@ -38,6 +42,7 @@ sealed interface TextReference {
fun TextReference.resolveReference(): String {
return when (this) {
is TextReference.Res -> stringResource(id, *formatArgs.toTypedArray())
+ is TextReference.PluralRes -> pluralStringResource(id, count, *formatArgs.toTypedArray())
is TextReference.Str -> value
}
}
\ No newline at end of file
diff --git a/core/ui/src/main/java/com/tangem/core/ui/res/TangemDimens.kt b/core/ui/src/main/java/com/tangem/core/ui/res/TangemDimens.kt
index 421c82c9e1..c3f075ffb0 100644
--- a/core/ui/src/main/java/com/tangem/core/ui/res/TangemDimens.kt
+++ b/core/ui/src/main/java/com/tangem/core/ui/res/TangemDimens.kt
@@ -20,6 +20,7 @@ data class TangemDimens internal constructor(
val elevation24: Dp = 24.dp,
// endregion Elevation
// region Radius
+ val radius0: Dp = 0.dp,
val radius2: Dp = 2.dp,
val radius3: Dp = 3.dp,
val radius4: Dp = 4.dp,
@@ -27,8 +28,10 @@ data class TangemDimens internal constructor(
val radius8: Dp = 8.dp,
val radius10: Dp = 10.dp,
val radius12: Dp = 12.dp,
+ val radius14: Dp = 14.dp,
val radius16: Dp = 16.dp,
val radius18: Dp = 18.dp,
+ val radius24: Dp = 24.dp,
val radius28: Dp = 28.dp,
// endregion Radius
// region Size
@@ -72,10 +75,12 @@ data class TangemDimens internal constructor(
val size116: Dp = 116.dp,
val size120: Dp = 120.dp,
val size142: Dp = 142.dp,
+ val size158: Dp = 158.dp,
val size164: Dp = 164.dp,
val size200: Dp = 200.dp,
// endregion Size
// region Spacing
+ val spacing0: Dp = 0.dp,
val spacing0_5: Dp = 0.5.dp,
val spacing2: Dp = 2.dp,
val spacing4: Dp = 4.dp,
@@ -91,6 +96,7 @@ data class TangemDimens internal constructor(
val spacing24: Dp = 24.dp,
val spacing26: Dp = 26.dp,
val spacing28: Dp = 28.dp,
+ val spacing30: Dp = 30.dp,
val spacing32: Dp = 32.dp,
val spacing34: Dp = 34.dp,
val spacing36: Dp = 34.dp,
diff --git a/core/ui/src/main/res/drawable/img_azero_22.xml b/core/ui/src/main/res/drawable/img_azero_22.xml
new file mode 100644
index 0000000000..9a9fd4a2f1
--- /dev/null
+++ b/core/ui/src/main/res/drawable/img_azero_22.xml
@@ -0,0 +1,12 @@
+
+
+
+
diff --git a/core/ui/src/main/res/drawable/img_telos_22.xml b/core/ui/src/main/res/drawable/img_telos_22.xml
new file mode 100644
index 0000000000..3250c06998
--- /dev/null
+++ b/core/ui/src/main/res/drawable/img_telos_22.xml
@@ -0,0 +1,15 @@
+
+
+
+
diff --git a/core/utils/src/main/java/com/tangem/utils/extensions/Any.kt b/core/utils/src/main/java/com/tangem/utils/extensions/Any.kt
new file mode 100644
index 0000000000..a4847c4bc2
--- /dev/null
+++ b/core/utils/src/main/java/com/tangem/utils/extensions/Any.kt
@@ -0,0 +1,10 @@
+package com.tangem.utils.extensions
+
+import java.lang.ref.WeakReference
+
+/**
+[REDACTED_AUTHOR]
+ */
+fun T.toWeakReference(): WeakReference {
+ return WeakReference(this)
+}
\ No newline at end of file
diff --git a/data/source/preferences/src/main/kotlin/com/tangem/data/source/preferences/storage/UsedCardsPrefStorage.kt b/data/source/preferences/src/main/kotlin/com/tangem/data/source/preferences/storage/UsedCardsPrefStorage.kt
index b1fbf61361..de987e84fc 100644
--- a/data/source/preferences/src/main/kotlin/com/tangem/data/source/preferences/storage/UsedCardsPrefStorage.kt
+++ b/data/source/preferences/src/main/kotlin/com/tangem/data/source/preferences/storage/UsedCardsPrefStorage.kt
@@ -68,6 +68,10 @@ class UsedCardsPrefStorage internal constructor(
return cardInfo.isActivationStarted && !cardInfo.isActivationFinished
}
+ fun hadFinishedActivation(): Boolean {
+ return restore().any { it.isActivationFinished }
+ }
+
private fun findCardInfo(
cardId: String,
list: MutableList? = null,
diff --git a/app/src/main/java/com/tangem/tap/domain/tokens/models/BlockchainNetwork.kt b/domain/legacy/src/main/java/com/tangem/domain/common/BlockchainNetwork.kt
similarity index 97%
rename from app/src/main/java/com/tangem/tap/domain/tokens/models/BlockchainNetwork.kt
rename to domain/legacy/src/main/java/com/tangem/domain/common/BlockchainNetwork.kt
index 32cfbc4bec..212bd764be 100644
--- a/app/src/main/java/com/tangem/tap/domain/tokens/models/BlockchainNetwork.kt
+++ b/domain/legacy/src/main/java/com/tangem/domain/common/BlockchainNetwork.kt
@@ -1,12 +1,12 @@
-package com.tangem.tap.domain.tokens.models
+package com.tangem.domain.common
import com.squareup.moshi.JsonClass
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.Token
import com.tangem.blockchain.common.WalletManager
import com.tangem.common.extensions.calculateHashCode
-import com.tangem.domain.models.scan.CardDTO
import com.tangem.domain.common.TapWorkarounds.derivationStyle
+import com.tangem.domain.models.scan.CardDTO
@JsonClass(generateAdapter = true)
data class BlockchainNetwork(
diff --git a/domain/legacy/src/main/java/com/tangem/domain/common/CardTypesResolver.kt b/domain/legacy/src/main/java/com/tangem/domain/common/CardTypesResolver.kt
index 72e1bfb243..ed40b0b3b6 100644
--- a/domain/legacy/src/main/java/com/tangem/domain/common/CardTypesResolver.kt
+++ b/domain/legacy/src/main/java/com/tangem/domain/common/CardTypesResolver.kt
@@ -4,14 +4,26 @@ import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.Token
interface CardTypesResolver {
+
fun isTangemNote(): Boolean
+
fun isTangemWallet(): Boolean
+
+ fun isWhiteWallet(): Boolean
+
fun isWallet2(): Boolean
+
fun isTangemTwins(): Boolean
+
fun isStart2Coin(): Boolean
+ fun isDev(): Boolean
+
fun isMultiwalletAllowed(): Boolean
fun getBlockchain(): Blockchain
+
fun getPrimaryToken(): Token?
+
+ fun getBackupCardsCount(): Int
}
\ No newline at end of file
diff --git a/domain/legacy/src/main/java/com/tangem/domain/common/TangemCardTypesResolver.kt b/domain/legacy/src/main/java/com/tangem/domain/common/TangemCardTypesResolver.kt
index 79f908088a..39991063b5 100644
--- a/domain/legacy/src/main/java/com/tangem/domain/common/TangemCardTypesResolver.kt
+++ b/domain/legacy/src/main/java/com/tangem/domain/common/TangemCardTypesResolver.kt
@@ -11,27 +11,37 @@ import com.tangem.domain.common.TapWorkarounds.isTestCard
import com.tangem.domain.models.scan.CardDTO
import com.tangem.domain.models.scan.ProductType
-class TangemCardTypesResolver(
+internal class TangemCardTypesResolver(
private val card: CardDTO,
private val productType: ProductType,
private val walletData: WalletData?,
) : CardTypesResolver {
override fun isTangemNote(): Boolean = productType == ProductType.Note
- override fun isTangemWallet(): Boolean = card.settings.isBackupAllowed &&
- card.settings.isHDWalletAllowed &&
- card.firmwareVersion >= FirmwareVersion.MultiWalletAvailable
- override fun isWallet2(): Boolean =
- card.firmwareVersion >= FirmwareVersion.KeysImportAvailable && card.settings.isKeysImportAllowed
+ override fun isTangemWallet(): Boolean {
+ return card.settings.isBackupAllowed && card.settings.isHDWalletAllowed &&
+ card.firmwareVersion >= FirmwareVersion.MultiWalletAvailable
+ }
+
+ override fun isWhiteWallet(): Boolean {
+ return walletData == null && card.firmwareVersion >= FirmwareVersion.HDWalletAvailable
+ }
+
+ override fun isWallet2(): Boolean {
+ return card.firmwareVersion >= FirmwareVersion.KeysImportAvailable && card.settings.isKeysImportAllowed
+ }
override fun isTangemTwins(): Boolean = productType == ProductType.Twins
+
override fun isStart2Coin(): Boolean = card.isStart2Coin
- override fun isMultiwalletAllowed(): Boolean = !isTangemTwins() &&
- !card.isStart2Coin &&
- !isTangemNote() &&
- (multiWalletAvailable() || card.wallets.firstOrNull()?.curve == EllipticCurve.Secp256k1)
+ override fun isDev(): Boolean = card.isTestCard
+
+ override fun isMultiwalletAllowed(): Boolean {
+ return !isTangemTwins() && !card.isStart2Coin && !isTangemNote() &&
+ (multiWalletAvailable() || card.wallets.firstOrNull()?.curve == EllipticCurve.Secp256k1)
+ }
private fun multiWalletAvailable() = card.firmwareVersion >= FirmwareVersion.MultiWalletAvailable
@@ -59,19 +69,21 @@ class TangemCardTypesResolver(
cardToken.decimals,
)
}
-}
-private fun Blockchain.Companion.fromBlockchainName(blockchainName: String): Blockchain {
- // workaround for BSC (BNB) notes cards
- return when (blockchainName) {
- "BINANCE" -> {
- Blockchain.BSC
- }
- "BINANCE/test" -> {
- Blockchain.BSCTestnet
- }
- else -> {
- Blockchain.fromId(blockchainName)
+ override fun getBackupCardsCount(): Int = card.wallets.size
+
+ private fun Blockchain.Companion.fromBlockchainName(blockchainName: String): Blockchain {
+ // workaround for BSC (BNB) notes cards
+ return when (blockchainName) {
+ "BINANCE" -> {
+ Blockchain.BSC
+ }
+ "BINANCE/test" -> {
+ Blockchain.BSCTestnet
+ }
+ else -> {
+ Blockchain.fromId(blockchainName)
+ }
}
}
}
\ No newline at end of file
diff --git a/domain/legacy/src/main/java/com/tangem/domain/common/extensions/Blockchain.kt b/domain/legacy/src/main/java/com/tangem/domain/common/extensions/Blockchain.kt
index de6329b343..15fb408bde 100644
--- a/domain/legacy/src/main/java/com/tangem/domain/common/extensions/Blockchain.kt
+++ b/domain/legacy/src/main/java/com/tangem/domain/common/extensions/Blockchain.kt
@@ -29,6 +29,7 @@ fun Blockchain.Companion.fromNetworkId(networkId: String): Blockchain? {
"bitcoin-cash/test" -> Blockchain.BitcoinCashTestnet
"cardano" -> Blockchain.CardanoShelley
"dogecoin" -> Blockchain.Dogecoin
+ "ducatus" -> Blockchain.Ducatus
"litecoin" -> Blockchain.Litecoin
"rootstock" -> Blockchain.RSK
"stellar" -> Blockchain.Stellar
@@ -59,6 +60,10 @@ fun Blockchain.Companion.fromNetworkId(networkId: String): Blockchain? {
"terra" -> Blockchain.TerraV1
"terra-2" -> Blockchain.TerraV2
"cronos" -> Blockchain.Cronos
+ "telos" -> Blockchain.Telos
+ "telos/test" -> Blockchain.TelosTestnet
+ "aleph-zero" -> Blockchain.AlephZero
+ "aleph-zero/test" -> Blockchain.AlephZeroTestnet
else -> null
}
}
@@ -82,6 +87,7 @@ fun Blockchain.toNetworkId(): String {
Blockchain.Cardano -> "cardano"
Blockchain.CardanoShelley -> "cardano"
Blockchain.Dogecoin -> "dogecoin"
+ Blockchain.Ducatus -> "ducatus"
Blockchain.Ethereum -> "ethereum"
Blockchain.EthereumTestnet -> "ethereum/test"
Blockchain.EthereumClassic -> "ethereum-classic"
@@ -122,6 +128,10 @@ fun Blockchain.toNetworkId(): String {
Blockchain.TerraV1 -> "terra"
Blockchain.TerraV2 -> "terra-2"
Blockchain.Cronos -> "cronos"
+ Blockchain.Telos -> "telos"
+ Blockchain.TelosTestnet -> "telos/test"
+ Blockchain.AlephZero -> "aleph-zero"
+ Blockchain.AlephZeroTestnet -> "aleph-zero/test"
}
}
@@ -142,6 +152,7 @@ fun Blockchain.toCoinId(): String {
Blockchain.Fantom, Blockchain.FantomTestnet -> "fantom"
Blockchain.Tron, Blockchain.TronTestnet -> "tron"
Blockchain.Polkadot, Blockchain.PolkadotTestnet -> "polkadot"
+ Blockchain.Ducatus -> "ducatus"
Blockchain.Litecoin -> "litecoin"
Blockchain.RSK -> "rootstock"
Blockchain.Tezos -> "tezos"
@@ -162,6 +173,8 @@ fun Blockchain.toCoinId(): String {
Blockchain.TerraV1 -> "terra-luna"
Blockchain.TerraV2 -> "terra-luna-2"
Blockchain.Cronos -> "crypto-com-chain"
+ Blockchain.Telos, Blockchain.TelosTestnet -> "telos"
+ Blockchain.AlephZero, Blockchain.AlephZeroTestnet -> "aleph-zero"
}
}
@@ -169,4 +182,7 @@ fun Blockchain.isSupportedInApp(): Boolean {
return !excludedBlockchains.contains(this)
}
-private val excludedBlockchains = listOf(Blockchain.Unknown)
\ No newline at end of file
+private val excludedBlockchains = listOf(
+ Blockchain.Unknown,
+ Blockchain.Ducatus,
+)
\ No newline at end of file
diff --git a/domain/legacy/src/main/java/com/tangem/domain/common/util/UserWalletId.kt b/domain/legacy/src/main/java/com/tangem/domain/common/util/UserWalletId.kt
deleted file mode 100644
index 17c22839fd..0000000000
--- a/domain/legacy/src/main/java/com/tangem/domain/common/util/UserWalletId.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.tangem.domain.common.util
-
-import com.tangem.common.extensions.hexToBytes
-import com.tangem.common.extensions.toHexString
-
-class UserWalletId(
- val stringValue: String,
-) {
- val value = stringValue.hexToBytes()
-
- constructor(value: ByteArray?) : this(
- stringValue = value?.toHexString() ?: "",
- )
-
- override fun equals(other: Any?): Boolean {
- if (this === other) return true
- if (other !is UserWalletId) return false
-
- if (stringValue != other.stringValue) return false
-
- return true
- }
-
- override fun hashCode(): Int {
- return stringValue.hashCode()
- }
-
- @Suppress("MagicNumber")
- override fun toString(): String {
- return with(stringValue) {
- "UserWalletId(${take(3)}...${takeLast(3)})"
- }
- }
-}
\ No newline at end of file
diff --git a/domain/legacy/src/main/java/com/tangem/domain/redux/global/DomainGlobalHub.kt b/domain/legacy/src/main/java/com/tangem/domain/redux/global/DomainGlobalHub.kt
index 37f01870cc..f22a14aa64 100644
--- a/domain/legacy/src/main/java/com/tangem/domain/redux/global/DomainGlobalHub.kt
+++ b/domain/legacy/src/main/java/com/tangem/domain/redux/global/DomainGlobalHub.kt
@@ -36,6 +36,7 @@ private class DomainGlobalReducer : ReStoreReducer {
return when (action) {
is DomainGlobalAction.SaveScanNoteResponse -> {
val card = action.scanResponse.card
+ // TODO: AuthHeaders: try to remove it, because now we can use headers with dynamic values
state.networkServices.tangemTechService.addAuthenticationHeader(
RequestHeader.AuthenticationHeader(
object : AuthProvider {
diff --git a/domain/wallets/.gitignore b/domain/wallets/.gitignore
new file mode 100644
index 0000000000..42afabfd2a
--- /dev/null
+++ b/domain/wallets/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/domain/wallets/build.gradle.kts b/domain/wallets/build.gradle.kts
new file mode 100644
index 0000000000..a9a1449956
--- /dev/null
+++ b/domain/wallets/build.gradle.kts
@@ -0,0 +1,27 @@
+plugins {
+ alias(deps.plugins.android.library)
+ alias(deps.plugins.kotlin.android)
+ id("configuration")
+}
+
+android {
+ namespace = "com.tangem.domain.wallets"
+}
+
+dependencies {
+
+ // region Domain modules
+ implementation(project(":domain:legacy"))
+ implementation(project(":domain:models"))
+ implementation(project(":domain:wallets:models"))
+ // endregion
+
+ // region Tangem libraries
+ implementation(deps.tangem.blockchain) // android-library
+ implementation(deps.tangem.card.core)
+ // endregion
+
+ // region Other libraries
+ implementation(deps.kotlin.coroutines)
+ // endregion
+}
\ No newline at end of file
diff --git a/domain/wallets/models/.gitignore b/domain/wallets/models/.gitignore
new file mode 100644
index 0000000000..42afabfd2a
--- /dev/null
+++ b/domain/wallets/models/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/domain/wallets/models/build.gradle.kts b/domain/wallets/models/build.gradle.kts
new file mode 100644
index 0000000000..537d724d84
--- /dev/null
+++ b/domain/wallets/models/build.gradle.kts
@@ -0,0 +1,14 @@
+plugins {
+ alias(deps.plugins.kotlin.jvm)
+ id("configuration")
+}
+
+dependencies {
+ // region Tangem libraries
+ implementation(deps.tangem.card.core)
+ // endregion
+
+ // region Domain modules
+ implementation(project(":domain:models"))
+ // endregion
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/domain/model/UserWallet.kt b/domain/wallets/models/src/main/java/com/tangem/domain/wallets/models/UserWallet.kt
similarity index 93%
rename from app/src/main/java/com/tangem/tap/domain/model/UserWallet.kt
rename to domain/wallets/models/src/main/java/com/tangem/domain/wallets/models/UserWallet.kt
index d58a3e7122..af407822fb 100644
--- a/app/src/main/java/com/tangem/tap/domain/model/UserWallet.kt
+++ b/domain/wallets/models/src/main/java/com/tangem/domain/wallets/models/UserWallet.kt
@@ -1,7 +1,6 @@
-package com.tangem.tap.domain.model
+package com.tangem.domain.wallets.models
import com.tangem.domain.models.scan.ScanResponse
-import com.tangem.domain.common.util.UserWalletId
/**
* Represents user's wallet which stored in app persistence
diff --git a/domain/wallets/models/src/main/java/com/tangem/domain/wallets/models/UserWalletId.kt b/domain/wallets/models/src/main/java/com/tangem/domain/wallets/models/UserWalletId.kt
new file mode 100644
index 0000000000..791c3a1059
--- /dev/null
+++ b/domain/wallets/models/src/main/java/com/tangem/domain/wallets/models/UserWalletId.kt
@@ -0,0 +1,13 @@
+package com.tangem.domain.wallets.models
+
+import com.tangem.common.extensions.hexToBytes
+import com.tangem.common.extensions.toHexString
+
+data class UserWalletId(val stringValue: String) {
+
+ val value = stringValue.hexToBytes()
+
+ constructor(value: ByteArray?) : this(stringValue = value?.toHexString() ?: "")
+
+ override fun toString() = "UserWalletId(${stringValue.take(n = 3)}...${stringValue.takeLast(n = 3)})"
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/domain/userWalletList/UserWalletsListManager.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/legacy/UserWalletsListManager.kt
similarity index 67%
rename from app/src/main/java/com/tangem/tap/domain/userWalletList/UserWalletsListManager.kt
rename to domain/wallets/src/main/java/com/tangem/domain/wallets/legacy/UserWalletsListManager.kt
index b1c97b594b..ff4e805ad1 100644
--- a/app/src/main/java/com/tangem/tap/domain/userWalletList/UserWalletsListManager.kt
+++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/legacy/UserWalletsListManager.kt
@@ -1,108 +1,105 @@
-package com.tangem.tap.domain.userWalletList
+package com.tangem.domain.wallets.legacy
import com.tangem.common.CompletionResult
-import com.tangem.domain.common.util.UserWalletId
-import com.tangem.tap.domain.model.UserWallet
+import com.tangem.domain.wallets.models.UserWallet
+import com.tangem.domain.wallets.models.UserWalletId
import kotlinx.coroutines.flow.Flow
interface UserWalletsListManager {
- /**
- * [Flow] with all saved [UserWallet]s updates
- * */
+
+ /** [Flow] with all saved [UserWallet]s updates */
val userWallets: Flow>
- /**
- * [Flow] with selected [UserWallet] updates
- * */
+ /** [Flow] with selected [UserWallet] updates */
val selectedUserWallet: Flow
- /**
- * Selected [UserWallet]
- * */
+ /** Selected [UserWallet] */
val selectedUserWalletSync: UserWallet?
- /**
- * Indicates that the [UserWalletsListManager] contains at least one saved [UserWallet]
- * */
+ /** Indicates that the [UserWalletsListManager] contains at least one saved [UserWallet] */
val hasUserWallets: Boolean
+ /** Count of saved user wallets */
+ val walletsCount: Int
+
/**
* Set [UserWallet] with provided [UserWalletId] as selected
*
* @param userWalletId [UserWalletId] of [UserWallet] which must be selected
*
- * @return [CompletionResult.Success] with selected [UserWallet]
- * or [CompletionResult.Failure] with [NoSuchElementException] if [UserWallet] with [userWalletId] not found
- * */
+ * @return [CompletionResult.Success] with selected [UserWallet] or [CompletionResult.Failure] with
+ * [NoSuchElementException] if [UserWallet] with [userWalletId] not found
+ */
suspend fun select(userWalletId: UserWalletId): CompletionResult
/**
* Save provided user wallet and set it as selected
+ *
* @param userWallet [UserWallet] to save
* @param canOverride If false, then terminate with [UserWalletsListError.WalletAlreadySaved] when user tries
* to save an already saved card
+ *
* @return [CompletionResult] of operation
*/
suspend fun save(userWallet: UserWallet, canOverride: Boolean = false): CompletionResult
/**
- * Same as [save] but not change selected user wallet ID
- * and not terminate with [UserWalletsListError.WalletAlreadySaved] if [UserWallet] already saved
+ * Same as [save] but not change selected user wallet ID and not terminate with
+ * [UserWalletsListError.WalletAlreadySaved] if [UserWallet] already saved.
+ * Can terminate with [NoSuchElementException] if unable to find [UserWallet] with provided [UserWalletId].
*
- * Can terminate with [NoSuchElementException] if unable to find [UserWallet] with provided [UserWalletId]
* @param userWalletId update [UserWallet] with that [UserWalletId]
* @param update lambda that receives stored [UserWallet] and returns updated [UserWallet]
- * @return [CompletionResult.Success] with updated [UserWallet]
- * or [CompletionResult.Failure] with [NoSuchElementException] if [UserWallet] with [userWalletId] not found
- * */
+ *
+ * @return [CompletionResult.Success] with updated [UserWallet] or [CompletionResult.Failure] with
+ * [NoSuchElementException] if [UserWallet] with [userWalletId] not found
+ */
suspend fun update(
userWalletId: UserWalletId,
update: suspend (UserWallet) -> UserWallet,
): CompletionResult
/**
- * Delete saved [UserWallet]s with provided [UserWalletId]s
- *
- * Sets [isLocked] as true if [userWallets] is empty or if all [userWallets] are locked
+ * Delete saved [UserWallet]s with provided [UserWalletId]s.
+ * Sets [isLocked] as true if [userWallets] is empty or if all [userWallets] are locked.
*
* @param userWalletIds [UserWalletId]s of [UserWallet]s which must be deleted
*
* @return [CompletionResult] of operation
- * */
+ */
suspend fun delete(userWalletIds: List): CompletionResult
/**
* Clear all saved [UserWallet]s and set [isLocked] as true
*
* @return [CompletionResult] of operation
- * */
+ */
suspend fun clear(): CompletionResult
/**
* Get [UserWallet] with provided [UserWalletId]
*
- * @return [CompletionResult.Success] with found [UserWallet]
- * or [CompletionResult.Failure] with [NoSuchElementException] if [UserWallet] with [userWalletId] not found
- * */
+ * @return [CompletionResult.Success] with found [UserWallet] or [CompletionResult.Failure] with
+ * [NoSuchElementException] if [UserWallet] with [userWalletId] not found
+ */
suspend fun get(userWalletId: UserWalletId): CompletionResult
interface Lockable : UserWalletsListManager {
+
/**
* Indicates that all [UserWallet]s is locked
*
* @see [isLockedSync]
* @see [UserWallet.isLocked]
- * */
+ */
val isLocked: Flow
/**
- * Indicates that all [UserWallet]s is locked
- *
- * Sync version
+ * Indicates that all [UserWallet]s is locked. Sync version.
*
* @see [isLocked]
* @see [UserWallet.isLocked]
- * */
+ */
val isLockedSync: Boolean
/**
@@ -110,12 +107,10 @@ interface UserWalletsListManager {
*
* @return [CompletionResult] of operation, with selected [UserWallet]
* or null if there is no selected [UserWallet]
- * */
+ */
suspend fun unlock(): CompletionResult
- /**
- * Remove [UserWallet]s from [userWallets] and set [isLocked] as true
- * */
+ /** Remove [UserWallet]s from [userWallets] and set [isLocked] as true */
fun lock()
}
diff --git a/app/src/main/java/com/tangem/tap/domain/walletStores/repository/WalletManagersRepository.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/legacy/WalletManagersRepository.kt
similarity index 75%
rename from app/src/main/java/com/tangem/tap/domain/walletStores/repository/WalletManagersRepository.kt
rename to domain/wallets/src/main/java/com/tangem/domain/wallets/legacy/WalletManagersRepository.kt
index c49f863277..10eb7a6669 100644
--- a/app/src/main/java/com/tangem/tap/domain/walletStores/repository/WalletManagersRepository.kt
+++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/legacy/WalletManagersRepository.kt
@@ -1,13 +1,14 @@
-package com.tangem.tap.domain.walletStores.repository
+package com.tangem.domain.wallets.legacy
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.WalletManager
import com.tangem.common.CompletionResult
-import com.tangem.domain.common.util.UserWalletId
-import com.tangem.tap.domain.model.UserWallet
-import com.tangem.tap.domain.tokens.models.BlockchainNetwork
+import com.tangem.domain.common.BlockchainNetwork
+import com.tangem.domain.wallets.models.UserWallet
+import com.tangem.domain.wallets.models.UserWalletId
interface WalletManagersRepository {
+
suspend fun findOrMakeMultiCurrencyWalletManager(
userWallet: UserWallet,
blockchainNetwork: BlockchainNetwork,
diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/legacy/WalletsStateHolder.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/legacy/WalletsStateHolder.kt
new file mode 100644
index 0000000000..3c7b38bbbe
--- /dev/null
+++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/legacy/WalletsStateHolder.kt
@@ -0,0 +1,6 @@
+package com.tangem.domain.wallets.legacy
+
+interface WalletsStateHolder {
+
+ val userWalletsListManager: UserWalletsListManager?
+}
\ No newline at end of file
diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetWalletsUseCase.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetWalletsUseCase.kt
new file mode 100644
index 0000000000..3c589f1bcd
--- /dev/null
+++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetWalletsUseCase.kt
@@ -0,0 +1,20 @@
+package com.tangem.domain.wallets.usecase
+
+import com.tangem.domain.wallets.legacy.WalletsStateHolder
+import com.tangem.domain.wallets.models.UserWallet
+import kotlinx.coroutines.flow.Flow
+
+/**
+ * Use case for getting list of user wallets
+ *
+ * @property walletsStateHolder state holder for getting static initialized 'userWalletsListManager'
+ *
+[REDACTED_AUTHOR]
+ */
+class GetWalletsUseCase(private val walletsStateHolder: WalletsStateHolder) {
+
+ @Throws(IllegalArgumentException::class)
+ operator fun invoke(): Flow> {
+ return requireNotNull(walletsStateHolder.userWalletsListManager).userWallets
+ }
+}
\ No newline at end of file
diff --git a/features/learn2earn/api/.gitignore b/features/learn2earn/api/.gitignore
new file mode 100644
index 0000000000..42afabfd2a
--- /dev/null
+++ b/features/learn2earn/api/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/features/learn2earn/api/build.gradle.kts b/features/learn2earn/api/build.gradle.kts
new file mode 100644
index 0000000000..7ff7fb7522
--- /dev/null
+++ b/features/learn2earn/api/build.gradle.kts
@@ -0,0 +1,4 @@
+plugins {
+ alias(deps.plugins.kotlin.jvm)
+ id("configuration")
+}
\ No newline at end of file
diff --git a/features/learn2earn/impl/.gitignore b/features/learn2earn/impl/.gitignore
new file mode 100644
index 0000000000..42afabfd2a
--- /dev/null
+++ b/features/learn2earn/impl/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/features/learn2earn/impl/build.gradle.kts b/features/learn2earn/impl/build.gradle.kts
new file mode 100644
index 0000000000..26d0179187
--- /dev/null
+++ b/features/learn2earn/impl/build.gradle.kts
@@ -0,0 +1,56 @@
+plugins {
+ alias(deps.plugins.android.library)
+ alias(deps.plugins.kotlin.android)
+ alias(deps.plugins.kotlin.kapt)
+ alias(deps.plugins.kotlin.serialization)
+ alias(deps.plugins.hilt.android)
+ id("configuration")
+}
+
+dependencies {
+ /** Core modules */
+ implementation(project(":common"))
+ implementation(project(":core:analytics"))
+ implementation(project(":core:featuretoggles"))
+ implementation(project(":core:datasource"))
+ implementation(project(":core:utils"))
+ implementation(project(":core:ui"))
+ implementation(project(":core:res"))
+ implementation(project(":data:source:preferences"))
+ implementation(project(":libs:auth"))
+ implementation(project(":libs:crypto"))
+
+ implementation(deps.material)
+
+ /** AndroidX */
+ implementation(deps.androidx.core.ktx)
+ implementation(deps.androidx.appCompat)
+ implementation(deps.androidx.fragment.ktx)
+ implementation(deps.androidx.activity.compose)
+ implementation(deps.androidx.browser)
+
+ /** Compose */
+ implementation(deps.compose.material)
+ implementation(deps.compose.material3)
+ implementation(deps.compose.foundation)
+ implementation(deps.compose.ui)
+ implementation(deps.compose.ui.tooling)
+
+ /** Preferences */
+ implementation(deps.krateSharedPref)
+
+ /** Network */
+ implementation(deps.moshi)
+ implementation(deps.moshi.kotlin)
+ implementation(deps.retrofit)
+ implementation(deps.retrofit.moshi)
+
+ /** Other libraries */
+ implementation(deps.kotlin.immutable.collections)
+ implementation(deps.kotlin.serialization)
+ implementation(deps.timber)
+
+ /** DI */
+ implementation(deps.hilt.android)
+ kapt(deps.hilt.kapt)
+}
\ No newline at end of file
diff --git a/features/learn2earn/impl/src/main/AndroidManifest.xml b/features/learn2earn/impl/src/main/AndroidManifest.xml
new file mode 100644
index 0000000000..472f44a1a5
--- /dev/null
+++ b/features/learn2earn/impl/src/main/AndroidManifest.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/analytics/Learn2earnEvents.kt b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/analytics/Learn2earnEvents.kt
new file mode 100644
index 0000000000..164fa4e793
--- /dev/null
+++ b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/analytics/Learn2earnEvents.kt
@@ -0,0 +1,70 @@
+package com.tangem.feature.learn2earn.analytics
+
+import com.tangem.core.analytics.AnalyticsEvent
+
+internal sealed class Learn2earnEvents(
+ category: String,
+ event: String,
+ params: Map = mapOf(),
+) : AnalyticsEvent(
+ category = category,
+ event = event,
+ params = params + mapOf(
+ "Program Name" to "1inch",
+ ),
+) {
+
+ sealed class IntroductionProcess(
+ event: String,
+ params: Map = mapOf(),
+ ) : Learn2earnEvents(
+ category = "Introduction Process",
+ event = event,
+ params = params,
+ ) {
+ class ButtonLearn : IntroductionProcess("Button - Learn")
+ }
+
+ sealed class MainScreen(
+ event: String,
+ params: Map = mapOf(),
+ ) : Learn2earnEvents(
+ category = "Main Screen",
+ event = event,
+ params = params,
+ ) {
+ class NoticeLear2earn(clientType: AnalyticsParam.ClientType) : MainScreen(
+ event = "Notice - Learn&Earn",
+ params = mapOf(AnalyticsParam.CLIENT_TYPE to clientType.value),
+ )
+
+ class NoticeClaimSuccess : MainScreen("Notice - Claim Successed")
+ }
+
+ sealed class PromoScreen(
+ event: String,
+ params: Map = mapOf(),
+ ) : Learn2earnEvents(
+ category = "Promo Screen",
+ event = event,
+ params = params,
+ ) {
+ class ButtonBuy : PromoScreen("Button - Buy")
+
+ class SuccessScreenOpened(clientType: AnalyticsParam.ClientType) : PromoScreen(
+ event = "Success Screen Opened",
+ params = mapOf(AnalyticsParam.CLIENT_TYPE to clientType.value),
+ )
+ }
+}
+
+internal sealed class AnalyticsParam {
+ sealed class ClientType(val value: String) {
+ class New : ClientType("New")
+ class Old : ClientType("Old")
+ }
+
+ companion object Key {
+ const val CLIENT_TYPE = "Client type"
+ }
+}
\ No newline at end of file
diff --git a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/DefaultLearn2earnRepository.kt b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/DefaultLearn2earnRepository.kt
new file mode 100644
index 0000000000..c10f0d57bb
--- /dev/null
+++ b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/DefaultLearn2earnRepository.kt
@@ -0,0 +1,137 @@
+package com.tangem.feature.learn2earn.data
+
+import com.squareup.moshi.Moshi
+import com.tangem.datasource.api.promotion.PromotionApi
+import com.tangem.datasource.api.promotion.models.*
+import com.tangem.feature.learn2earn.data.api.Learn2earnPreferenceStorage
+import com.tangem.feature.learn2earn.data.api.Learn2earnRepository
+import com.tangem.feature.learn2earn.data.models.PromoUserData
+import com.tangem.utils.coroutines.AppCoroutineDispatcherProvider
+import kotlinx.coroutines.withContext
+import timber.log.Timber
+
+/**
+[REDACTED_AUTHOR]
+ */
+internal class DefaultLearn2earnRepository(
+ private val preferencesStorage: Learn2earnPreferenceStorage,
+ private val api: PromotionApi,
+ private val dispatchers: AppCoroutineDispatcherProvider,
+ moshi: Moshi,
+) : Learn2earnRepository {
+
+ private val promotionInfoAdapter = moshi.adapter(PromotionInfoResponse::class.java)
+ private val userDataAdapter = moshi.adapter(PromoUserData::class.java)
+
+ private var userData: PromoUserData = restoreUserData()
+
+ override fun getUserData(): PromoUserData {
+ return userData
+ }
+
+ override fun updateUserData(userData: PromoUserData) {
+ this.userData = userData
+ saveUserData(userData)
+ }
+
+ override fun getProgramName(): String {
+ return PROGRAM_NAME
+ }
+
+ override suspend fun getPromotionInfo(): Result {
+ return withContext(dispatchers.io) {
+ val promotionInfo = restorePromotionInfo()
+ val data = promotionInfo?.getData(userData.promoCode)
+ if (data?.status == PromotionInfoResponse.Status.FINISHED) {
+ Result.success(promotionInfo)
+ } else {
+ runCatching { api.getPromotionInfo(getProgramName()) }
+ .fold(
+ onSuccess = { infoResponse ->
+ savePromotionInfo(infoResponse)
+ Result.success(infoResponse)
+ },
+ onFailure = { exception -> Result.failure(exception) },
+ )
+ }
+ }
+ }
+
+ override suspend fun validate(walletId: String): ValidateResponse {
+ return withContext(dispatchers.io) {
+ api.validate(ValidateRequestBody(walletId, getProgramName()))
+ }
+ }
+
+ override suspend fun requestAward(walletId: String, address: String): AwardResponse {
+ return withContext(dispatchers.io) {
+ api.requestAward(AwardRequestBody(walletId, address, getProgramName()))
+ }
+ }
+
+ override suspend fun validateCode(walletId: String, code: String?): CodeValidateResponse {
+ return withContext(dispatchers.io) {
+ api.validateCode(CodeValidateRequestBody(walletId, code))
+ }
+ }
+
+ override suspend fun requestAwardByCode(walletId: String, address: String, code: String?): CodeAwardResponse {
+ return withContext(dispatchers.io) {
+ api.requestAwardByCode(CodeAwardRequestBody(walletId, address, code))
+ }
+ }
+
+ private fun restorePromotionInfo(): PromotionInfoResponse? {
+ return try {
+ preferencesStorage.promotionInfo?.let { promotionInfoAdapter.fromJson(it) }
+ } catch (ex: Exception) {
+ Timber.e(ex)
+ preferencesStorage.promotionInfo = null
+ null
+ }
+ }
+
+ private fun savePromotionInfo(infoResponse: PromotionInfoResponse) {
+ try {
+ preferencesStorage.promotionInfo = promotionInfoAdapter.toJson(infoResponse)
+ } catch (ex: Exception) {
+ Timber.e(ex)
+ }
+ }
+
+ private fun restoreUserData(): PromoUserData {
+ return try {
+ preferencesStorage.userData?.let { userDataAdapter.fromJson(it) }
+ ?: createEmptyUserData().apply { saveUserData(this) }
+ } catch (ex: Exception) {
+ Timber.e(ex)
+ createEmptyUserData().apply { saveUserData(this) }
+ }
+ }
+
+ private fun saveUserData(userData: PromoUserData) {
+ try {
+ preferencesStorage.userData = userDataAdapter.toJson(userData)
+ } catch (ex: Exception) {
+ Timber.e(ex)
+ }
+ }
+
+ private fun createEmptyUserData(): PromoUserData = PromoUserData(
+ promoCode = null,
+ isRegisteredInPromotion = false,
+ isAlreadyReceivedAward = false,
+ )
+
+ private companion object {
+ const val PROGRAM_NAME: String = "1inch"
+ }
+}
+
+private fun PromotionInfoResponse.getData(promoCode: String?): PromotionInfoResponse.Data? {
+ return if (promoCode == null) {
+ newCard
+ } else {
+ oldCard
+ }
+}
\ No newline at end of file
diff --git a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/DefaultPreferenceStorage.kt b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/DefaultPreferenceStorage.kt
new file mode 100644
index 0000000000..4c3e39b9ae
--- /dev/null
+++ b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/DefaultPreferenceStorage.kt
@@ -0,0 +1,19 @@
+package com.tangem.feature.learn2earn.data
+
+import android.content.Context
+import com.tangem.feature.learn2earn.data.api.Learn2earnPreferenceStorage
+import hu.autsoft.krate.SimpleKrate
+import hu.autsoft.krate.default.withDefault
+import hu.autsoft.krate.stringPref
+
+/**
+[REDACTED_AUTHOR]
+ */
+internal class DefaultPreferenceStorage(
+ context: Context,
+) : SimpleKrate(context = context, name = "Lear2earnPromotion"), Learn2earnPreferenceStorage {
+
+ override var promotionInfo: String? by stringPref().withDefault(null)
+
+ override var userData: String? by stringPref().withDefault(null)
+}
\ No newline at end of file
diff --git a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/api/Learn2earnPreferenceStorage.kt b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/api/Learn2earnPreferenceStorage.kt
new file mode 100644
index 0000000000..8c8840bb74
--- /dev/null
+++ b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/api/Learn2earnPreferenceStorage.kt
@@ -0,0 +1,11 @@
+package com.tangem.feature.learn2earn.data.api
+
+/**
+[REDACTED_AUTHOR]
+ */
+interface Learn2earnPreferenceStorage {
+
+ var promotionInfo: String?
+
+ var userData: String?
+}
\ No newline at end of file
diff --git a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/api/Learn2earnRepository.kt b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/api/Learn2earnRepository.kt
new file mode 100644
index 0000000000..06e95628d7
--- /dev/null
+++ b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/api/Learn2earnRepository.kt
@@ -0,0 +1,26 @@
+package com.tangem.feature.learn2earn.data.api
+
+import com.tangem.datasource.api.promotion.models.*
+import com.tangem.feature.learn2earn.data.models.PromoUserData
+
+/**
+[REDACTED_AUTHOR]
+ */
+interface Learn2earnRepository {
+
+ fun getUserData(): PromoUserData
+
+ fun updateUserData(userData: PromoUserData)
+
+ fun getProgramName(): String
+
+ suspend fun getPromotionInfo(): Result
+
+ suspend fun validate(walletId: String): ValidateResponse
+
+ suspend fun requestAward(walletId: String, address: String): AwardResponse
+
+ suspend fun validateCode(walletId: String, code: String?): CodeValidateResponse
+
+ suspend fun requestAwardByCode(walletId: String, address: String, code: String?): CodeAwardResponse
+}
\ No newline at end of file
diff --git a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/di/Learn2earnDataModule.kt b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/di/Learn2earnDataModule.kt
new file mode 100644
index 0000000000..186b3c8458
--- /dev/null
+++ b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/di/Learn2earnDataModule.kt
@@ -0,0 +1,45 @@
+package com.tangem.feature.learn2earn.data.di
+
+import android.content.Context
+import com.squareup.moshi.Moshi
+import com.tangem.datasource.api.promotion.PromotionApi
+import com.tangem.datasource.di.NetworkMoshi
+import com.tangem.datasource.di.PromotionOneInch
+import com.tangem.feature.learn2earn.data.DefaultLearn2earnRepository
+import com.tangem.feature.learn2earn.data.DefaultPreferenceStorage
+import com.tangem.feature.learn2earn.data.api.Learn2earnPreferenceStorage
+import com.tangem.feature.learn2earn.data.api.Learn2earnRepository
+import com.tangem.utils.coroutines.AppCoroutineDispatcherProvider
+import dagger.Module
+import dagger.Provides
+import dagger.hilt.InstallIn
+import dagger.hilt.android.qualifiers.ApplicationContext
+import dagger.hilt.components.SingletonComponent
+import javax.inject.Singleton
+
+@Module
+@InstallIn(SingletonComponent::class)
+internal class Learn2earnDataModule {
+
+ @Provides
+ @Singleton
+ fun providePreferenceStorage(@ApplicationContext context: Context): Learn2earnPreferenceStorage {
+ return DefaultPreferenceStorage(context)
+ }
+
+ @Provides
+ @Singleton
+ fun provideRepository(
+ preferenceStorage: Learn2earnPreferenceStorage,
+ @NetworkMoshi moshi: Moshi,
+ @PromotionOneInch promotionApi: PromotionApi,
+ dispatchers: AppCoroutineDispatcherProvider,
+ ): Learn2earnRepository {
+ return DefaultLearn2earnRepository(
+ preferencesStorage = preferenceStorage,
+ api = promotionApi,
+ dispatchers = dispatchers,
+ moshi = moshi,
+ )
+ }
+}
\ No newline at end of file
diff --git a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/models/PromoUserData.kt b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/models/PromoUserData.kt
new file mode 100644
index 0000000000..7edf1bc122
--- /dev/null
+++ b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/models/PromoUserData.kt
@@ -0,0 +1,10 @@
+package com.tangem.feature.learn2earn.data.models
+
+/**
+[REDACTED_AUTHOR]
+ */
+data class PromoUserData(
+ val promoCode: String?,
+ val isRegisteredInPromotion: Boolean,
+ val isAlreadyReceivedAward: Boolean,
+)
\ No newline at end of file
diff --git a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/toggles/DefaultLearn2earnFeatureToggleManager.kt b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/toggles/DefaultLearn2earnFeatureToggleManager.kt
new file mode 100644
index 0000000000..19306c2aed
--- /dev/null
+++ b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/toggles/DefaultLearn2earnFeatureToggleManager.kt
@@ -0,0 +1,14 @@
+package com.tangem.feature.learn2earn.data.toggles
+
+import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
+
+/**
+[REDACTED_AUTHOR]
+ */
+internal class DefaultLearn2earnFeatureToggleManager(
+ private val featureTogglesManager: FeatureTogglesManager,
+) : Learn2earnFeatureToggleManager {
+
+ override val isLearn2earnEnabled: Boolean
+ get() = featureTogglesManager.isFeatureEnabled(name = "1INCH_LEARN_2_EARN_ENABLED")
+}
\ No newline at end of file
diff --git a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/toggles/Learn2earnFeatureToggleManager.kt b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/toggles/Learn2earnFeatureToggleManager.kt
new file mode 100644
index 0000000000..64f5c4abfc
--- /dev/null
+++ b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/toggles/Learn2earnFeatureToggleManager.kt
@@ -0,0 +1,11 @@
+package com.tangem.feature.learn2earn.data.toggles
+
+/**
+ * Feature toggles manager implementation of "learn2earn" feature
+ *
+[REDACTED_AUTHOR]
+ */
+interface Learn2earnFeatureToggleManager {
+
+ val isLearn2earnEnabled: Boolean
+}
\ No newline at end of file
diff --git a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/domain/DefaultLearn2earnInteractor.kt b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/domain/DefaultLearn2earnInteractor.kt
new file mode 100644
index 0000000000..402f88ee82
--- /dev/null
+++ b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/domain/DefaultLearn2earnInteractor.kt
@@ -0,0 +1,306 @@
+package com.tangem.feature.learn2earn.domain
+
+import android.net.Uri
+import com.tangem.core.analytics.api.AnalyticsEventHandler
+import com.tangem.datasource.api.promotion.models.AbstractPromotionResponse
+import com.tangem.datasource.api.promotion.models.PromotionInfoResponse
+import com.tangem.feature.learn2earn.data.api.Learn2earnRepository
+import com.tangem.feature.learn2earn.data.models.PromoUserData
+import com.tangem.feature.learn2earn.data.toggles.Learn2earnFeatureToggleManager
+import com.tangem.feature.learn2earn.domain.api.*
+import com.tangem.feature.learn2earn.domain.models.Promotion
+import com.tangem.feature.learn2earn.domain.models.PromotionError
+import com.tangem.feature.learn2earn.domain.models.toDomainError
+import com.tangem.lib.crypto.DerivationManager
+import com.tangem.lib.crypto.UserWalletManager
+import com.tangem.lib.crypto.models.Currency
+
+/**
+[REDACTED_AUTHOR]
+ */
+internal class DefaultLearn2earnInteractor(
+ private val featureToggleManager: Learn2earnFeatureToggleManager,
+ private val repository: Learn2earnRepository,
+ private val userWalletManager: UserWalletManager,
+ private val derivationManager: DerivationManager,
+ private val analyticsEventHandler: AnalyticsEventHandler,
+ dependencyProvider: Learn2earnDependencyProvider,
+) : Learn2earnInteractor {
+
+ override var webViewResultHandler: WebViewResultHandler? = null
+
+ private lateinit var promotion: Promotion
+
+ private val webViewUriBuilder: WebViewUriBuilder by lazy {
+ WebViewUriBuilder(
+ authCredentialsProvider = dependencyProvider.getWebViewAuthCredentialsProvider(),
+ userCountryCodeProvider = dependencyProvider.getUserCountryCodeProvider(),
+ promoCodeProvider = { repository.getUserData().promoCode },
+ )
+ }
+
+ private val webViewUriParser: WebViewUriParser by lazy {
+ WebViewUriParser { repository.getProgramName() }
+ }
+
+ override suspend fun init() {
+ initPromotionInfo()
+ }
+
+ override fun isUserHadPromoCode(): Boolean {
+ return repository.getUserData().promoCode != null
+ }
+
+ override fun isNeedToShowViewOnStoriesScreen(): Boolean {
+ return promotionIsActive()
+ }
+
+ override suspend fun isNeedToShowViewOnMainScreen(): Boolean {
+ if (!promotionIsActive()) return false
+
+ val promoCode = repository.getUserData().promoCode
+ val userWalletId = userWalletManager.getWalletId()
+ return if (promoCode == null) {
+ val response = repository.validate(userWalletId)
+ response.valid == true
+ } else {
+ val response = repository.validateCode(userWalletId, promoCode)
+ when (val error = response.error?.toDomainError()) {
+ null -> response.valid == true
+ else -> error !is PromotionError.CodeWasNotAppliedInShop
+ }
+ }
+ }
+
+ override fun isUserRegisteredInPromotion(): Boolean {
+ return repository.getUserData().isRegisteredInPromotion
+ }
+
+ override fun getAwardAmount(): Int {
+ val promoCode = repository.getUserData().promoCode
+ val awardAmount = promotion.getPromotionInfo().getData(promoCode).award.toInt()
+
+ return awardAmount
+ }
+
+ override fun getAwardNetworkName(): String {
+ val networkId = promotion.getPromotionInfo().awardPaymentToken.networkId
+ return userWalletManager.getNativeTokenForNetwork(networkId).name
+ }
+
+ @Throws(IllegalArgumentException::class)
+ override suspend fun requestAward(): Result {
+ val awardCurrency = getCurrencyForAward()
+ ?: return Result.failure(PromotionError.UnknownError("Currency for award is null"))
+
+ val walletId = userWalletManager.getWalletId()
+ val promoCode = repository.getUserData().promoCode
+
+ val error = if (promoCode == null) {
+ requestAward(walletId, awardCurrency)
+ } else {
+ requestAwardWithPromoCode(walletId, awardCurrency, promoCode)
+ }
+
+ return if (error == null) {
+ Result.success(Unit)
+ } else {
+ val domainError = error.toDomainError()
+ handlePromotionError(domainError)
+ Result.failure(domainError)
+ }
+ }
+
+ private suspend fun requestAward(walletId: String, awardCurrency: Currency): AbstractPromotionResponse.Error? {
+ val validateResponse = repository.validate(walletId)
+ return if (validateResponse.valid == true) {
+ val address = getWalletAddressForAward(awardCurrency)
+ val awardResponse = repository.requestAward(walletId, address)
+ if (awardResponse.status == true) {
+ updateUserData { it.copy(isAlreadyReceivedAward = true) }
+ null
+ } else {
+ awardResponse.error
+ }
+ } else {
+ validateResponse.error
+ }
+ }
+
+ private suspend fun requestAwardWithPromoCode(
+ walletId: String,
+ awardCurrency: Currency,
+ promoCode: String,
+ ): AbstractPromotionResponse.Error? {
+ val codeValidateResponse = repository.validateCode(walletId, promoCode)
+ return if (codeValidateResponse.valid == true) {
+ val address = getWalletAddressForAward(awardCurrency)
+ val awardWithCodeResponse = repository.requestAwardByCode(walletId, address, promoCode)
+ if (awardWithCodeResponse.status == true) {
+ updateUserData { it.copy(isAlreadyReceivedAward = true) }
+ null
+ } else {
+ awardWithCodeResponse.error
+ }
+ } else {
+ codeValidateResponse.error
+ }
+ }
+
+ private suspend fun getWalletAddressForAward(currency: Currency): String {
+ val derivationPath = deriveOrAddTokens(currency)
+ return userWalletManager.getWalletAddress(currency.networkId, derivationPath)
+ }
+
+ private suspend fun deriveOrAddTokens(currency: Currency): String {
+ val derivationPath = derivationManager.getDerivationPathForBlockchain(currency.networkId)
+ if (derivationPath.isNullOrEmpty()) error("derivationPath shouldn't be empty")
+
+ if (!derivationManager.hasDerivation(currency.networkId, derivationPath)) {
+ derivationManager.deriveMissingBlockchains(currency)
+ }
+ if (!userWalletManager.isTokenAdded(currency, derivationPath)) {
+ userWalletManager.addToken(currency, derivationPath)
+ }
+ return derivationPath
+ }
+
+ private fun handlePromotionError(error: PromotionError) {
+ when (error) {
+ is PromotionError.CodeNotFound -> {
+ updateUserData { it.copy(promoCode = null) }
+ }
+ is PromotionError.CardAlreadyHasAward, is PromotionError.WalletAlreadyHasAward,
+ is PromotionError.CodeWasAlreadyUsed,
+ -> {
+ updateUserData { it.copy(isAlreadyReceivedAward = true) }
+ }
+ else -> Unit
+ }
+ }
+
+ override fun buildUriForNewUser(): Uri {
+ return webViewUriBuilder.buildUriForNewUser()
+ }
+
+ override fun buildUriForOldUser(): Uri {
+ return webViewUriBuilder.buildUriForOldUser()
+ }
+
+ override fun getBasicAuthHeaders(): ArrayList {
+ return HeadersConverter().convert(webViewUriBuilder.getBasicAuthHeaders())
+ }
+
+ override fun handleRedirect(uri: Uri): WebViewAction {
+ val result = webViewUriParser.parse(uri)
+ when (result) {
+ is WebViewResult.PromoCode -> {
+ updateUserData {
+ it.copy(
+ promoCode = result.promoCode,
+ isRegisteredInPromotion = true,
+ )
+ }
+ }
+ WebViewResult.ReadyForAward -> {
+ updateUserData { it.copy(isRegisteredInPromotion = true) }
+ }
+ is WebViewResult.Learn2earnAnalyticsEvent -> {
+ analyticsEventHandler.send(result.event)
+ }
+ WebViewResult.Empty -> Unit
+ }
+ webViewResultHandler?.handleResult(result)
+
+ return result.toWebViewAction()
+ }
+
+ private fun promotionIsActive(): Boolean {
+ val userData = repository.getUserData()
+ val isActive = when {
+ !featureToggleManager.isLearn2earnEnabled -> false
+ userData.isAlreadyReceivedAward -> false
+ promotion.isError() -> false
+ else -> {
+ val data = promotion.getPromotionInfo().getData(userData.promoCode)
+ data.status == PromotionInfoResponse.Status.ACTIVE
+ }
+ }
+
+ return isActive
+ }
+
+ private suspend fun initPromotionInfo() {
+ promotion = if (featureToggleManager.isLearn2earnEnabled) {
+ repository.getPromotionInfo()
+ .fold(
+ onSuccess = { response ->
+ val responseError = response.error
+ if (responseError == null) {
+ val npeMessage = { "Shouldn't be null" }
+ Promotion(
+ info = Promotion.PromotionInfo(
+ newCard = requireNotNull(response.newCard, npeMessage),
+ oldCard = requireNotNull(response.oldCard, npeMessage),
+ awardPaymentToken = requireNotNull(response.awardPaymentToken, npeMessage),
+ ),
+ error = null,
+ )
+ } else {
+ Promotion(
+ info = null,
+ error = responseError.toDomainError(),
+ )
+ }
+ },
+ onFailure = {
+ Promotion(
+ info = null,
+ error = PromotionError.NetworkUnreachable,
+ )
+ },
+ )
+ } else {
+ Promotion(
+ info = null,
+ error = null,
+ )
+ }
+ }
+
+ private fun getCurrencyForAward(): Currency? {
+ val token = promotion.info?.awardPaymentToken ?: return null
+
+ return Currency.NonNativeToken(
+ id = token.id,
+ name = token.name,
+ symbol = token.symbol,
+ networkId = token.networkId,
+ contractAddress = token.contractAddress,
+ decimalCount = token.decimalCount,
+ )
+ }
+
+ private fun updateUserData(updateBlock: (PromoUserData) -> PromoUserData): PromoUserData {
+ return updateBlock(repository.getUserData()).apply {
+ repository.updateUserData(this)
+ }
+ }
+
+ private fun Promotion.PromotionInfo.getData(promoCode: String?): PromotionInfoResponse.Data {
+ return if (promoCode == null) {
+ newCard
+ } else {
+ oldCard
+ }
+ }
+
+ private fun WebViewResult.toWebViewAction(): WebViewAction {
+ return when (this) {
+ WebViewResult.Empty -> WebViewAction.PROCEED
+ WebViewResult.ReadyForAward -> WebViewAction.FINISH_SESSION
+ is WebViewResult.Learn2earnAnalyticsEvent -> WebViewAction.NOTHING
+ is WebViewResult.PromoCode -> WebViewAction.NOTHING
+ }
+ }
+}
\ No newline at end of file
diff --git a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/domain/HeadersConverter.kt b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/domain/HeadersConverter.kt
new file mode 100644
index 0000000000..439091ba1a
--- /dev/null
+++ b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/domain/HeadersConverter.kt
@@ -0,0 +1,28 @@
+package com.tangem.feature.learn2earn.domain
+
+import com.tangem.utils.converter.TwoWayConverter
+
+/**
+ * A converter that helps prepare a list of headers to be added to the Bundle.
+ * ArrayList is used to prevent cast exceptions when the convert result is placed in a Bundle.
+ * @see Learn2earnRouter#openWebView() putStringArrayListExtra
+ *
+[REDACTED_AUTHOR]
+ */
+internal class HeadersConverter : TwoWayConverter