Updated on 2026-08-14
This commit is contained in:
commit
82c92f8180
639 changed files with 18827 additions and 2682 deletions
|
|
@ -3,9 +3,11 @@ package com.tangem.tap
|
|||
import com.tangem.TangemSdkLogger
|
||||
import com.tangem.blockchainsdk.BlockchainSDKFactory
|
||||
import com.tangem.blockchainsdk.signer.TransactionSignerFactory
|
||||
import com.tangem.blockchainsdk.utils.ExcludedBlockchains
|
||||
import com.tangem.common.routing.AppRouter
|
||||
import com.tangem.core.analytics.filter.OneTimeEventFilter
|
||||
import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
|
||||
import com.tangem.core.configtoggle.blockchain.ExcludedBlockchainsManager
|
||||
import com.tangem.core.configtoggle.feature.FeatureTogglesManager
|
||||
import com.tangem.core.navigation.share.ShareManager
|
||||
import com.tangem.core.navigation.url.UrlOpener
|
||||
import com.tangem.datasource.connection.NetworkConnectionManager
|
||||
|
|
@ -34,6 +36,7 @@ import com.tangem.tap.common.log.TangemAppLoggerInitializer
|
|||
import com.tangem.tap.domain.scanCard.CardScanningFeatureToggles
|
||||
import com.tangem.tap.features.home.featuretoggles.HomeFeatureToggles
|
||||
import com.tangem.tap.proxy.AppStateHolder
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import dagger.hilt.EntryPoint
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
|
|
@ -52,6 +55,8 @@ interface ApplicationEntryPoint {
|
|||
|
||||
fun getFeatureTogglesManager(): FeatureTogglesManager
|
||||
|
||||
fun getExcludedBlockchainsManager(): ExcludedBlockchainsManager
|
||||
|
||||
fun getNetworkConnectionManager(): NetworkConnectionManager
|
||||
|
||||
fun getCardScanningFeatureToggles(): CardScanningFeatureToggles
|
||||
|
|
@ -113,4 +118,8 @@ interface ApplicationEntryPoint {
|
|||
fun getOnrampFeatureToggles(): OnrampFeatureToggles
|
||||
|
||||
fun getOnboardingV2FeatureToggles(): OnboardingV2FeatureToggles
|
||||
|
||||
fun getCoroutineDispatcherProvider(): CoroutineDispatcherProvider
|
||||
|
||||
fun getExcludedBlockchains(): ExcludedBlockchains
|
||||
}
|
||||
|
|
@ -52,6 +52,7 @@ import com.tangem.domain.tokens.GetPolkadotCheckHasResetUseCase
|
|||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.feature.qrscanning.QrScanningRouter
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.WalletScreenAnalyticsEvent
|
||||
import com.tangem.features.onboarding.v2.OnboardingV2FeatureToggles
|
||||
import com.tangem.features.pushnotifications.api.navigation.PushNotificationsRouter
|
||||
import com.tangem.features.pushnotifications.api.utils.PUSH_PERMISSION
|
||||
import com.tangem.features.send.api.navigation.SendRouter
|
||||
|
|
@ -59,6 +60,7 @@ import com.tangem.features.staking.api.navigation.StakingRouter
|
|||
import com.tangem.features.tokendetails.navigation.TokenDetailsRouter
|
||||
import com.tangem.features.wallet.navigation.WalletRouter
|
||||
import com.tangem.operations.backup.BackupService
|
||||
import com.tangem.sdk.api.BackupServiceHolder
|
||||
import com.tangem.sdk.api.TangemSdkManager
|
||||
import com.tangem.sdk.extensions.init
|
||||
import com.tangem.tap.common.ActivityResultCallbackHolder
|
||||
|
|
@ -72,6 +74,7 @@ import com.tangem.tap.common.redux.NotificationsHandler
|
|||
import com.tangem.tap.domain.walletconnect2.domain.WalletConnectInteractor
|
||||
import com.tangem.tap.features.intentHandler.IntentProcessor
|
||||
import com.tangem.tap.features.intentHandler.handlers.BackgroundScanIntentHandler
|
||||
import com.tangem.tap.features.intentHandler.handlers.OnPushClickedIntentHandler
|
||||
import com.tangem.tap.features.intentHandler.handlers.WalletConnectLinkIntentHandler
|
||||
import com.tangem.tap.features.main.MainViewModel
|
||||
import com.tangem.tap.features.main.model.Toast
|
||||
|
|
@ -186,6 +189,12 @@ class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbac
|
|||
@Inject
|
||||
lateinit var shouldInitiallyAskPermissionUseCase: ShouldInitiallyAskPermissionUseCase
|
||||
|
||||
@Inject
|
||||
lateinit var backupServiceHolder: BackupServiceHolder
|
||||
|
||||
@Inject
|
||||
lateinit var onboardingV2FeatureToggles: OnboardingV2FeatureToggles
|
||||
|
||||
internal val viewModel: MainViewModel by viewModels()
|
||||
|
||||
private lateinit var appThemeModeFlow: SharedFlow<AppThemeMode>
|
||||
|
|
@ -295,7 +304,14 @@ class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbac
|
|||
cardSdkOwner.register(activity = this)
|
||||
tangemSdkManager = injectedTangemSdkManager
|
||||
appStateHolder.tangemSdkManager = tangemSdkManager
|
||||
backupService = BackupService.init(cardSdkConfigRepository.sdk, this)
|
||||
|
||||
if (onboardingV2FeatureToggles.isOnboardingV2Enabled) {
|
||||
backupServiceHolder.createAndSetService(cardSdkConfigRepository.sdk, this)
|
||||
backupService = backupServiceHolder.backupService.get()!! // will be deleted eventually
|
||||
} else {
|
||||
backupService = BackupService.init(cardSdkConfigRepository.sdk, this)
|
||||
}
|
||||
|
||||
lockUserWalletsTimer = LockUserWalletsTimer(
|
||||
owner = this,
|
||||
settingsRepository = settingsRepository,
|
||||
|
|
@ -382,6 +398,7 @@ class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbac
|
|||
|
||||
private fun initIntentHandlers() {
|
||||
val hasSavedWalletsProvider = { userWalletsListManager.hasUserWallets }
|
||||
intentProcessor.addHandler(OnPushClickedIntentHandler(analyticsEventsHandler))
|
||||
intentProcessor.addHandler(BackgroundScanIntentHandler(hasSavedWalletsProvider, lifecycleScope))
|
||||
intentProcessor.addHandler(WalletConnectLinkIntentHandler())
|
||||
}
|
||||
|
|
@ -555,6 +572,7 @@ class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbac
|
|||
}
|
||||
}
|
||||
|
||||
// TODO add onboarding v2 handling
|
||||
store.dispatch(BackupAction.CheckForUnfinishedBackup)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import com.tangem.TangemSdkLogger
|
|||
import com.tangem.blockchain.network.BlockchainSdkRetrofitBuilder
|
||||
import com.tangem.blockchainsdk.BlockchainSDKFactory
|
||||
import com.tangem.blockchainsdk.signer.TransactionSignerFactory
|
||||
import com.tangem.blockchainsdk.utils.ExcludedBlockchains
|
||||
import com.tangem.common.routing.AppRouter
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.core.analytics.api.ParamsInterceptor
|
||||
|
|
@ -17,7 +18,8 @@ import com.tangem.core.analytics.models.AnalyticsEvent
|
|||
import com.tangem.core.analytics.models.AnalyticsParam
|
||||
import com.tangem.core.analytics.models.Basic
|
||||
import com.tangem.core.analytics.models.Basic.TransactionSent.WalletForm
|
||||
import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
|
||||
import com.tangem.core.configtoggle.blockchain.ExcludedBlockchainsManager
|
||||
import com.tangem.core.configtoggle.feature.FeatureTogglesManager
|
||||
import com.tangem.datasource.api.common.MoshiConverter
|
||||
import com.tangem.datasource.api.common.createNetworkLoggingInterceptor
|
||||
import com.tangem.datasource.connection.NetworkConnectionManager
|
||||
|
|
@ -57,9 +59,11 @@ import com.tangem.tap.domain.tasks.product.DerivationsFinder
|
|||
import com.tangem.tap.features.home.featuretoggles.HomeFeatureToggles
|
||||
import com.tangem.tap.proxy.AppStateHolder
|
||||
import com.tangem.tap.proxy.redux.DaggerGraphState
|
||||
import com.tangem.utils.coroutines.AppCoroutineDispatcherProvider
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.wallet.BuildConfig
|
||||
import dagger.hilt.EntryPoints
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.rekotlin.Store
|
||||
import com.tangem.tap.domain.walletconnect2.domain.LegacyWalletConnectRepository as WalletConnect2Repository
|
||||
|
|
@ -88,6 +92,9 @@ abstract class TangemApplication : Application(), ImageLoaderFactory {
|
|||
private val featureTogglesManager: FeatureTogglesManager
|
||||
get() = entryPoint.getFeatureTogglesManager()
|
||||
|
||||
private val excludedBlockchainsManager: ExcludedBlockchainsManager
|
||||
get() = entryPoint.getExcludedBlockchainsManager()
|
||||
|
||||
private val networkConnectionManager: NetworkConnectionManager
|
||||
get() = entryPoint.getNetworkConnectionManager()
|
||||
|
||||
|
|
@ -180,6 +187,12 @@ abstract class TangemApplication : Application(), ImageLoaderFactory {
|
|||
|
||||
private val onboardingV2FeatureToggles: OnboardingV2FeatureToggles
|
||||
get() = entryPoint.getOnboardingV2FeatureToggles()
|
||||
|
||||
private val dispatchers: CoroutineDispatcherProvider
|
||||
get() = entryPoint.getCoroutineDispatcherProvider()
|
||||
|
||||
private val excludedBlockchains: ExcludedBlockchains
|
||||
get() = entryPoint.getExcludedBlockchains()
|
||||
// endregion
|
||||
|
||||
override fun onCreate() {
|
||||
|
|
@ -200,9 +213,11 @@ abstract class TangemApplication : Application(), ImageLoaderFactory {
|
|||
// TODO: Try to performance and user experience.
|
||||
// [REDACTED_JIRA]
|
||||
runBlocking {
|
||||
featureTogglesManager.init()
|
||||
|
||||
initWithConfigDependency(environmentConfig = environmentConfigStorage.initialize())
|
||||
awaitAll(
|
||||
async { featureTogglesManager.init() },
|
||||
async { excludedBlockchainsManager.init() },
|
||||
async { initWithConfigDependency(environmentConfig = environmentConfigStorage.initialize()) },
|
||||
)
|
||||
}
|
||||
|
||||
loadNativeLibraries()
|
||||
|
|
@ -216,7 +231,7 @@ abstract class TangemApplication : Application(), ImageLoaderFactory {
|
|||
|
||||
derivationsFinder = DerivationsFinder(
|
||||
appPreferencesStore = appPreferencesStore,
|
||||
dispatchers = AppCoroutineDispatcherProvider(),
|
||||
dispatchers = dispatchers,
|
||||
)
|
||||
appStateHolder.mainStore = store
|
||||
|
||||
|
|
@ -258,6 +273,7 @@ abstract class TangemApplication : Application(), ImageLoaderFactory {
|
|||
onrampFeatureToggles = onrampFeatureToggles,
|
||||
environmentConfigStorage = environmentConfigStorage,
|
||||
onboardingV2FeatureToggles = onboardingV2FeatureToggles,
|
||||
excludedBlockchains = excludedBlockchains,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -140,6 +140,11 @@ class DialogManager : StoreSubscriber<GlobalState> {
|
|||
message = state.dialog.error.message,
|
||||
context = context,
|
||||
)
|
||||
is WalletConnectDialog.UnsupportedWcVersion -> SimpleAlertDialog.create(
|
||||
titleRes = R.string.common_error,
|
||||
messageRes = R.string.unsupported_wc_version,
|
||||
context = context,
|
||||
)
|
||||
is BackupDialog.AttestationFailed -> AttestationFailedDialog.create(context)
|
||||
is BackupDialog.AddMoreBackupCards -> AddMoreBackupCardsDialog.create(context)
|
||||
is BackupDialog.BackupInProgress -> BackupInProgressDialog.create(context)
|
||||
|
|
|
|||
|
|
@ -1,25 +0,0 @@
|
|||
package com.tangem.tap.common.analytics.events
|
||||
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
sealed class MainScreen(
|
||||
event: String,
|
||||
params: Map<String, String> = mapOf(),
|
||||
) : AnalyticsEvent("Main Screen", event, params) {
|
||||
|
||||
class ScreenOpened : MainScreen("Screen opened")
|
||||
class ButtonScanCard : MainScreen("Button - Scan Card")
|
||||
|
||||
class EnableBiometrics(state: AnalyticsParam.OnOffState) : MainScreen(
|
||||
event = "Enable Biometric",
|
||||
params = mapOf("State" to state.value),
|
||||
)
|
||||
|
||||
class NoticeRateAppButton(result: AnalyticsParam.RateApp) : MainScreen(
|
||||
event = "Notice - Rate The App Button Tapped",
|
||||
params = mapOf("Result" to result.value),
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.tangem.tap.common.analytics.events
|
||||
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
|
||||
internal sealed class Push(event: String) : AnalyticsEvent(
|
||||
category = "Push",
|
||||
event = event,
|
||||
params = emptyMap(),
|
||||
error = null,
|
||||
) {
|
||||
|
||||
data object PushNotificationOpened : Push(event = "Push Notification Opened")
|
||||
}
|
||||
|
|
@ -11,7 +11,7 @@ sealed class SignIn(
|
|||
error: Throwable? = null,
|
||||
) : AnalyticsEvent("Sign In", event, params, error) {
|
||||
|
||||
class ScreenOpened : SignIn(event = "Sing In Screen Opened")
|
||||
class ScreenOpened : SignIn(event = "Sign In Screen Opened")
|
||||
|
||||
class ButtonBiometricSignIn : SignIn(event = "Button - Biometric Sign In")
|
||||
class ButtonCardSignIn : SignIn(event = "Button - Card Sign In")
|
||||
|
|
|
|||
|
|
@ -12,11 +12,12 @@ internal sealed class WalletConnect(
|
|||
) : AnalyticsEvent("Wallet Connect", event, params, error) {
|
||||
|
||||
class ScreenOpened : WalletConnect(event = "WC Screen Opened")
|
||||
class NewSessionEstablished(dAppName: String, dAppUrl: String) : WalletConnect(
|
||||
class NewSessionEstablished(dAppName: String, dAppUrl: String, blockchainNames: List<String>) : WalletConnect(
|
||||
event = "New Session Established",
|
||||
params = mapOf(
|
||||
AnalyticsParam.DAPP_NAME to dAppName,
|
||||
AnalyticsParam.DAPP_URL to dAppUrl,
|
||||
AnalyticsParam.BLOCKCHAIN to blockchainNames.joinToString(","),
|
||||
),
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import com.tangem.domain.wallets.builder.UserWalletIdBuilder
|
|||
import com.tangem.tap.common.analytics.converters.ParamCardCurrencyConverter
|
||||
import com.tangem.tap.common.analytics.events.AnalyticsParam
|
||||
import com.tangem.tap.common.analytics.events.IntroductionProcess
|
||||
import com.tangem.tap.common.analytics.events.MainScreen
|
||||
import com.tangem.tap.common.extensions.inject
|
||||
import com.tangem.tap.features.demo.DemoHelper
|
||||
import com.tangem.tap.proxy.redux.DaggerGraphState
|
||||
|
|
@ -31,7 +30,7 @@ class CardContextInterceptor(
|
|||
|
||||
override fun canBeAppliedTo(event: AnalyticsEvent): Boolean {
|
||||
return when (event) {
|
||||
is IntroductionProcess.ButtonScanCard, is MainScreen.ButtonScanCard -> false
|
||||
is IntroductionProcess.ButtonScanCard -> false
|
||||
else -> true
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +0,0 @@
|
|||
package com.tangem.tap.common.extensions
|
||||
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.common.extensions.remove
|
||||
|
||||
fun Blockchain.getNetworkStandardName(): String {
|
||||
return when (this) {
|
||||
Blockchain.Ethereum, Blockchain.EthereumTestnet -> "ERC20"
|
||||
Blockchain.BSC, Blockchain.BSCTestnet -> "BEP20"
|
||||
Blockchain.Binance, Blockchain.BinanceTestnet -> "BEP2"
|
||||
Blockchain.Tron, Blockchain.TronTestnet -> "TRC20"
|
||||
Blockchain.TON -> "TON"
|
||||
else -> ""
|
||||
}
|
||||
}
|
||||
|
||||
val Blockchain.networkNameWithoutTestnet
|
||||
get() = this.getNetworkName().remove(" Testnet")
|
||||
|
|
@ -18,6 +18,7 @@ import com.google.firebase.messaging.RemoteMessage
|
|||
import com.tangem.domain.common.LogConfig
|
||||
import com.tangem.tap.MainActivity
|
||||
import com.tangem.tap.common.images.createCoilImageLoader
|
||||
import com.tangem.tap.features.intentHandler.handlers.OnPushClickedIntentHandler
|
||||
import com.tangem.wallet.R
|
||||
import timber.log.Timber
|
||||
|
||||
|
|
@ -37,6 +38,7 @@ internal class TangemPushNotificationService : FirebaseMessagingService() {
|
|||
|
||||
// TODO refactoring: [REDACTED_JIRA]
|
||||
val intent = Intent(applicationContext, MainActivity::class.java)
|
||||
intent.putExtra(OnPushClickedIntentHandler.IS_OPENED_FROM_PUSH, true)
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
||||
val pendingIntent = PendingIntent.getActivity(
|
||||
/* context = */ this,
|
||||
|
|
|
|||
|
|
@ -64,12 +64,16 @@ private fun handleAction(action: Action, appState: () -> AppState?) {
|
|||
}
|
||||
val cardProvider: () -> CardDTO? = { scanResponseProvider.invoke()?.card }
|
||||
|
||||
val buyService = makeBuyExchangeService(config)
|
||||
val sellService = makeSellExchangeService(config)
|
||||
val exchangeManager = CurrencyExchangeManager(
|
||||
buyService = makeBuyExchangeService(config),
|
||||
sellService = makeSellExchangeService(config),
|
||||
buyService = buyService,
|
||||
sellService = sellService,
|
||||
primaryRules = CardExchangeRules(cardProvider),
|
||||
)
|
||||
// TODO: for refactoring (after remove old design refactor CurrencyExchangeManager and use 1 instance)
|
||||
store.inject(DaggerGraphState::appStateHolder).buyService = buyService
|
||||
store.inject(DaggerGraphState::appStateHolder).sellService = sellService
|
||||
store.inject(DaggerGraphState::appStateHolder).exchangeService = exchangeManager
|
||||
store.dispatchOnMain(GlobalAction.ExchangeManager.Init.Success(exchangeManager))
|
||||
store.dispatchOnMain(GlobalAction.ExchangeManager.Update)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.tap.common.url
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import androidx.browser.customtabs.CustomTabColorSchemeParams
|
||||
import androidx.browser.customtabs.CustomTabsIntent
|
||||
|
|
@ -34,6 +35,8 @@ internal class CustomTabsUrlOpener : UrlOpener {
|
|||
)
|
||||
.build()
|
||||
|
||||
customTabsIntent.intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
|
||||
customTabsIntent.launchUrl(context, Uri.parse(url))
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +1,21 @@
|
|||
package com.tangem.tap.di
|
||||
|
||||
import com.tangem.blockchainsdk.utils.ExcludedBlockchains
|
||||
import com.tangem.datasource.exchangeservice.swap.SwapServiceLoader
|
||||
import com.tangem.domain.card.ScanCardUseCase
|
||||
import com.tangem.domain.card.repository.CardSdkConfigRepository
|
||||
import com.tangem.domain.exchange.RampStateManager
|
||||
import com.tangem.domain.tokens.GetNetworkCoinStatusUseCase
|
||||
import com.tangem.domain.tokens.GetPolkadotCheckHasImmortalUseCase
|
||||
import com.tangem.domain.tokens.GetPolkadotCheckHasResetUseCase
|
||||
import com.tangem.domain.tokens.repository.CurrenciesRepository
|
||||
import com.tangem.domain.tokens.repository.PolkadotAccountHealthCheckRepository
|
||||
import com.tangem.sdk.api.TangemSdkManager
|
||||
import com.tangem.tap.domain.scanCard.repository.DefaultScanCardRepository
|
||||
import com.tangem.tap.network.exchangeServices.DefaultRampManager
|
||||
import com.tangem.tap.proxy.AppStateHolder
|
||||
import com.tangem.utils.Provider
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
|
|
@ -39,8 +45,24 @@ internal object ActivityModule {
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideDefaultRampManager(appStateHolder: AppStateHolder): RampStateManager {
|
||||
return DefaultRampManager(appStateHolder.exchangeService)
|
||||
fun provideDefaultRampManager(
|
||||
appStateHolder: AppStateHolder,
|
||||
swapServiceLoader: SwapServiceLoader,
|
||||
currenciesRepository: CurrenciesRepository,
|
||||
getNetworkCoinStatusUseCase: GetNetworkCoinStatusUseCase,
|
||||
excludedBlockchains: ExcludedBlockchains,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
): RampStateManager {
|
||||
return DefaultRampManager(
|
||||
exchangeService = appStateHolder.exchangeService,
|
||||
buyService = Provider { requireNotNull(appStateHolder.buyService) },
|
||||
sellService = Provider { requireNotNull(appStateHolder.sellService) },
|
||||
swapServiceLoader = swapServiceLoader,
|
||||
currenciesRepository = currenciesRepository,
|
||||
getNetworkCoinStatusUseCase = getNetworkCoinStatusUseCase,
|
||||
excludedBlockchains = excludedBlockchains,
|
||||
dispatchers = dispatchers,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
|
|
|||
17
app/src/main/java/com/tangem/tap/di/TangemSdkModule.kt
Normal file
17
app/src/main/java/com/tangem/tap/di/TangemSdkModule.kt
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
package com.tangem.tap.di
|
||||
|
||||
import com.tangem.sdk.api.BackupServiceHolder
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
internal object TangemSdkModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideBackupServiceHolder(): BackupServiceHolder = BackupServiceHolder()
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.tap.di.data
|
||||
|
||||
import com.tangem.blockchainsdk.utils.ExcludedBlockchains
|
||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||
import com.tangem.domain.card.repository.DerivationsRepository
|
||||
import com.tangem.sdk.api.TangemSdkManager
|
||||
|
|
@ -20,8 +21,9 @@ internal object CardDataModule {
|
|||
fun providesDerivationsRepository(
|
||||
tangemSdkManager: TangemSdkManager,
|
||||
userWalletsStore: UserWalletsStore,
|
||||
excludedBlockchains: ExcludedBlockchains,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
): DerivationsRepository {
|
||||
return DefaultDerivationsRepository(tangemSdkManager, userWalletsStore, dispatchers)
|
||||
return DefaultDerivationsRepository(tangemSdkManager, userWalletsStore, excludedBlockchains, dispatchers)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.tap.di.domain
|
||||
|
||||
import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
|
||||
import com.tangem.core.configtoggle.feature.FeatureTogglesManager
|
||||
import com.tangem.domain.card.ScanCardProcessor
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.domain.wallets.usecase.GenerateWalletNameUseCase
|
||||
|
|
|
|||
160
app/src/main/java/com/tangem/tap/di/domain/OnrampDomainModule.kt
Normal file
160
app/src/main/java/com/tangem/tap/di/domain/OnrampDomainModule.kt
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
package com.tangem.tap.di.domain
|
||||
|
||||
import com.tangem.domain.onramp.*
|
||||
import com.tangem.domain.onramp.repositories.OnrampErrorResolver
|
||||
import com.tangem.domain.onramp.repositories.OnrampRepository
|
||||
import com.tangem.domain.onramp.repositories.OnrampTransactionRepository
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Suppress("TooManyFunctions")
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
internal object OnrampDomainModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideGetOnrampCurrenciesUseCase(onrampRepository: OnrampRepository): GetOnrampCurrenciesUseCase {
|
||||
return GetOnrampCurrenciesUseCase(onrampRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideOnrampSaveDefaultCurrencyUseCase(onrampRepository: OnrampRepository): OnrampSaveDefaultCurrencyUseCase {
|
||||
return OnrampSaveDefaultCurrencyUseCase(onrampRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideGetOnrampCountriesUseCase(onrampRepository: OnrampRepository): GetOnrampCountriesUseCase {
|
||||
return GetOnrampCountriesUseCase(onrampRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideGetOnrampCountryUseCase(onrampRepository: OnrampRepository): GetOnrampCountryUseCase {
|
||||
return GetOnrampCountryUseCase(onrampRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideOnrampSaveDefaultCountryUseCase(onrampRepository: OnrampRepository): OnrampSaveDefaultCountryUseCase {
|
||||
return OnrampSaveDefaultCountryUseCase(onrampRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideCheckOnrampAvailabilityUseCase(onrampRepository: OnrampRepository): CheckOnrampAvailabilityUseCase {
|
||||
return CheckOnrampAvailabilityUseCase(onrampRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideGetOnrampStatusUseCase(
|
||||
onrampRepository: OnrampRepository,
|
||||
onrampTransactionRepository: OnrampTransactionRepository,
|
||||
onrampErrorResolver: OnrampErrorResolver,
|
||||
): GetOnrampStatusUseCase {
|
||||
return GetOnrampStatusUseCase(
|
||||
onrampRepository,
|
||||
onrampTransactionRepository,
|
||||
onrampErrorResolver,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideGetOnrampCurrencyUseCase(onrampRepository: OnrampRepository): GetOnrampCurrencyUseCase {
|
||||
return GetOnrampCurrencyUseCase(onrampRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideGetOnrampTransactionsUseCase(
|
||||
onrampTransactionRepository: OnrampTransactionRepository,
|
||||
): GetOnrampTransactionsUseCase {
|
||||
return GetOnrampTransactionsUseCase(onrampTransactionRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideGetOnrampTransactionUseCase(
|
||||
onrampTransactionRepository: OnrampTransactionRepository,
|
||||
): GetOnrampTransactionUseCase {
|
||||
return GetOnrampTransactionUseCase(onrampTransactionRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideOnrampRemoveTransactionUseCase(
|
||||
onrampTransactionRepository: OnrampTransactionRepository,
|
||||
): OnrampRemoveTransactionUseCase {
|
||||
return OnrampRemoveTransactionUseCase(onrampTransactionRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideOnrampSaveTransactionUseCase(
|
||||
onrampTransactionRepository: OnrampTransactionRepository,
|
||||
): OnrampSaveTransactionUseCase {
|
||||
return OnrampSaveTransactionUseCase(onrampTransactionRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideGetOnrampPaymentMethodsUseCase(onrampRepository: OnrampRepository): GetOnrampPaymentMethodsUseCase {
|
||||
return GetOnrampPaymentMethodsUseCase(onrampRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideClearOnrampCacheUseCase(onrampRepository: OnrampRepository): ClearOnrampCacheUseCase {
|
||||
return ClearOnrampCacheUseCase(onrampRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideOnrampFetchQuotesUseCase(onrampRepository: OnrampRepository): OnrampFetchQuotesUseCase {
|
||||
return OnrampFetchQuotesUseCase(onrampRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideGetOnrampQuotesUseCase(onrampRepository: OnrampRepository): GetOnrampQuotesUseCase {
|
||||
return GetOnrampQuotesUseCase(onrampRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideGetOnrampSelectedPaymentMethodUseCase(
|
||||
onrampRepository: OnrampRepository,
|
||||
): GetOnrampSelectedPaymentMethodUseCase {
|
||||
return GetOnrampSelectedPaymentMethodUseCase(onrampRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideGetOnrampProviderWithQuoteUseCase(
|
||||
onrampRepository: OnrampRepository,
|
||||
): GetOnrampProviderWithQuoteUseCase {
|
||||
return GetOnrampProviderWithQuoteUseCase(onrampRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideOnrampSaveSelectedPaymentMethod(onrampRepository: OnrampRepository): OnrampSaveSelectedPaymentMethod {
|
||||
return OnrampSaveSelectedPaymentMethod(onrampRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideGetOnrampRedirectUrlUseCase(
|
||||
onrampRepository: OnrampRepository,
|
||||
transactionRepository: OnrampTransactionRepository,
|
||||
): GetOnrampRedirectUrlUseCase {
|
||||
return GetOnrampRedirectUrlUseCase(onrampRepository, transactionRepository)
|
||||
}
|
||||
}
|
||||
|
|
@ -133,14 +133,6 @@ internal object SettingsDomainModule {
|
|||
return ShouldShowRingPromoUseCase(promoSettingsRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideShouldShowTravalaPromoWalletUseCase(
|
||||
promoSettingsRepository: PromoSettingsRepository,
|
||||
): ShouldShowTravalaPromoWalletUseCase {
|
||||
return ShouldShowTravalaPromoWalletUseCase(promoSettingsRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideShouldShowSwapPromoTokenUseCase(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
package com.tangem.tap.di.domain
|
||||
|
||||
import com.tangem.feature.swap.domain.GetAvailablePairsUseCase
|
||||
import com.tangem.feature.swap.domain.api.SwapRepository
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import javax.inject.Singleton
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
internal object SwapDomainModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideGetAvailablePairsUseCase(swapRepository: SwapRepository): GetAvailablePairsUseCase {
|
||||
return GetAvailablePairsUseCase(swapRepository = swapRepository)
|
||||
}
|
||||
}
|
||||
|
|
@ -7,7 +7,6 @@ import com.tangem.domain.tokens.*
|
|||
import com.tangem.domain.tokens.repository.*
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
import com.tangem.feature.swap.domain.api.SwapRepository
|
||||
import com.tangem.features.staking.api.featuretoggles.StakingFeatureToggles
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
|
|
@ -119,26 +118,26 @@ internal object TokensDomainModule {
|
|||
currenciesRepository: CurrenciesRepository,
|
||||
quotesRepository: QuotesRepository,
|
||||
networksRepository: NetworksRepository,
|
||||
marketCryptoCurrencyRepository: MarketCryptoCurrencyRepository,
|
||||
swapRepository: SwapRepository,
|
||||
currencyChecksRepository: CurrencyChecksRepository,
|
||||
showSwapPromoTokenUseCase: ShouldShowSwapPromoTokenUseCase,
|
||||
promoRepository: PromoRepository,
|
||||
stakingRepository: StakingRepository,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
rampStateManager: RampStateManager,
|
||||
): GetCurrencyWarningsUseCase {
|
||||
return GetCurrencyWarningsUseCase(
|
||||
walletManagersFacade = walletManagersFacade,
|
||||
currenciesRepository = currenciesRepository,
|
||||
quotesRepository = quotesRepository,
|
||||
networksRepository = networksRepository,
|
||||
marketCryptoCurrencyRepository = marketCryptoCurrencyRepository,
|
||||
currencyChecksRepository = currencyChecksRepository,
|
||||
swapRepository = swapRepository,
|
||||
showSwapPromoTokenUseCase = showSwapPromoTokenUseCase,
|
||||
promoRepository = promoRepository,
|
||||
stakingRepository = stakingRepository,
|
||||
dispatchers = dispatchers,
|
||||
rampStateManager = rampStateManager,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -216,23 +215,19 @@ internal object TokensDomainModule {
|
|||
fun provideGetCryptoCurrencyActionsUseCase(
|
||||
rampStateManager: RampStateManager,
|
||||
walletManagersFacade: WalletManagersFacade,
|
||||
marketCryptoCurrencyRepository: MarketCryptoCurrencyRepository,
|
||||
currenciesRepository: CurrenciesRepository,
|
||||
quotesRepository: QuotesRepository,
|
||||
networksRepository: NetworksRepository,
|
||||
stakingRepository: StakingRepository,
|
||||
stakingFeatureToggles: StakingFeatureToggles,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
): GetCryptoCurrencyActionsUseCase {
|
||||
return GetCryptoCurrencyActionsUseCase(
|
||||
rampManager = rampStateManager,
|
||||
walletManagersFacade = walletManagersFacade,
|
||||
marketCryptoCurrencyRepository = marketCryptoCurrencyRepository,
|
||||
currenciesRepository = currenciesRepository,
|
||||
quotesRepository = quotesRepository,
|
||||
networksRepository = networksRepository,
|
||||
stakingRepository = stakingRepository,
|
||||
stakingFeatureToggles = stakingFeatureToggles,
|
||||
dispatchers = dispatchers,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.tap.domain.card
|
||||
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchainsdk.utils.ExcludedBlockchains
|
||||
import com.tangem.blockchainsdk.utils.fromNetworkId
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.common.card.EllipticCurve
|
||||
|
|
@ -32,6 +33,7 @@ private typealias DerivedKeys = Map<ByteArrayKey, ExtendedPublicKeysMap>
|
|||
internal class DefaultDerivationsRepository(
|
||||
private val tangemSdkManager: TangemSdkManager,
|
||||
private val userWalletsStore: UserWalletsStore,
|
||||
private val excludedBlockchains: ExcludedBlockchains,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
) : DerivationsRepository {
|
||||
|
||||
|
|
@ -49,6 +51,7 @@ internal class DefaultDerivationsRepository(
|
|||
blockchain = Blockchain.fromNetworkId(it.value) ?: return@mapNotNull null,
|
||||
extraDerivationPath = null,
|
||||
scanResponse = userWallet.scanResponse,
|
||||
excludedBlockchains = excludedBlockchains,
|
||||
)
|
||||
},
|
||||
)
|
||||
|
|
@ -85,6 +88,7 @@ internal class DefaultDerivationsRepository(
|
|||
blockchain = Blockchain.fromNetworkId(backendId) ?: return@mapNotNull null,
|
||||
extraDerivationPath = extraDerivationPath,
|
||||
scanResponse = userWallet.scanResponse,
|
||||
excludedBlockchains = excludedBlockchains,
|
||||
)
|
||||
},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.tap.domain.scanCard
|
||||
|
||||
import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
|
||||
import com.tangem.core.configtoggle.feature.FeatureTogglesManager
|
||||
|
||||
/**
|
||||
* Add custom token feature toggles
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import com.tangem.common.authentication.storage.AuthenticatedStorage
|
|||
import com.tangem.common.json.TangemSdkAdapter
|
||||
import com.tangem.common.services.secure.SecureStorage
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.domain.models.scan.serialization.*
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.sdk.storage.AndroidSecureStorage
|
||||
import com.tangem.sdk.storage.createEncryptedSharedPreferences
|
||||
|
|
@ -19,7 +20,6 @@ import com.tangem.tap.domain.userWalletList.repository.implementation.BiometricU
|
|||
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.*
|
||||
import com.tangem.tap.tangemSdkManager
|
||||
import com.tangem.utils.Provider
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
package com.tangem.tap.domain.userWalletList.utils
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
package com.tangem.tap.domain.userWalletList.utils.json
|
||||
|
||||
import com.squareup.moshi.FromJson
|
||||
import com.squareup.moshi.JsonAdapter
|
||||
import com.squareup.moshi.JsonReader
|
||||
import com.squareup.moshi.JsonWriter
|
||||
import com.squareup.moshi.ToJson
|
||||
import com.tangem.common.extensions.ByteArrayKey
|
||||
|
||||
internal class ByteArrayKeyAdapter {
|
||||
@ToJson
|
||||
fun toJson(writer: JsonWriter, src: ByteArrayKey, byteArrayAdapter: JsonAdapter<ByteArray>) {
|
||||
byteArrayAdapter.toJson(writer, src.bytes)
|
||||
}
|
||||
|
||||
@FromJson
|
||||
fun fromJson(reader: JsonReader, byteArrayAdapter: JsonAdapter<ByteArray>): ByteArrayKey? {
|
||||
return byteArrayAdapter.fromJson(reader)?.let {
|
||||
ByteArrayKey(bytes = it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
package com.tangem.tap.domain.userWalletList.utils.json
|
||||
|
||||
import com.squareup.moshi.FromJson
|
||||
import com.squareup.moshi.JsonAdapter
|
||||
import com.squareup.moshi.JsonReader
|
||||
import com.squareup.moshi.JsonWriter
|
||||
import com.squareup.moshi.ToJson
|
||||
import com.tangem.domain.models.scan.CardDTO
|
||||
|
||||
internal class CardBackupStatusAdapter {
|
||||
@ToJson
|
||||
fun toJson(writer: JsonWriter, src: CardDTO.BackupStatus?, mapAdapter: JsonAdapter<Map<String, String>>) {
|
||||
val jsonMap = mutableMapOf<String, String>()
|
||||
|
||||
when (src) {
|
||||
is CardDTO.BackupStatus.Active -> {
|
||||
jsonMap["status"] = "active"
|
||||
jsonMap["cardCount"] = src.cardCount.toString()
|
||||
}
|
||||
is CardDTO.BackupStatus.CardLinked -> {
|
||||
jsonMap["status"] = "card_linked"
|
||||
jsonMap["cardCount"] = src.cardCount.toString()
|
||||
}
|
||||
is CardDTO.BackupStatus.NoBackup -> {
|
||||
jsonMap["status"] = "no_backup"
|
||||
}
|
||||
null -> {
|
||||
jsonMap["status"] = "null"
|
||||
}
|
||||
}
|
||||
|
||||
mapAdapter.toJson(writer, jsonMap)
|
||||
}
|
||||
|
||||
@FromJson
|
||||
fun fromJson(reader: JsonReader, mapAdapter: JsonAdapter<Map<String, String>>): CardDTO.BackupStatus? {
|
||||
val map = mapAdapter.fromJson(reader) ?: return null
|
||||
|
||||
return when (map["status"]) {
|
||||
"active" -> CardDTO.BackupStatus.Active(
|
||||
cardCount = map["cardCount"]?.toInt() ?: 0,
|
||||
)
|
||||
"card_linked" -> CardDTO.BackupStatus.CardLinked(
|
||||
cardCount = map["cardCount"]?.toInt() ?: 0,
|
||||
)
|
||||
"no_backup" -> CardDTO.BackupStatus.NoBackup
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
package com.tangem.tap.domain.userWalletList.utils.json
|
||||
|
||||
import com.squareup.moshi.FromJson
|
||||
import com.squareup.moshi.ToJson
|
||||
import com.tangem.common.extensions.guard
|
||||
import com.tangem.common.json.MoshiJsonConverter
|
||||
import com.tangem.crypto.hdWallet.DerivationNode
|
||||
import com.tangem.crypto.hdWallet.DerivationPath
|
||||
import timber.log.Timber
|
||||
|
||||
class DerivationPathAdapterWithMigration {
|
||||
@ToJson
|
||||
fun toJson(src: DerivationPath): String = src.rawPath
|
||||
|
||||
@FromJson
|
||||
fun fromJson(json: String): DerivationPath {
|
||||
val jsonMap = MoshiJsonConverter.default().toMap(json)
|
||||
return if (jsonMap.isEmpty()) {
|
||||
DerivationPath(json)
|
||||
} else {
|
||||
fromLegacyScheme(jsonMap)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private fun fromLegacyScheme(jsonMap: Map<String, Any>): DerivationPath {
|
||||
val rawPath = jsonMap["rawPath"] as String
|
||||
val nodeIndexes = (jsonMap["nodes"] as? List<Number>).guard {
|
||||
Timber.e("Unable to convert derivation path nodes from JSON")
|
||||
return DerivationPath(rawPath)
|
||||
}
|
||||
val nodes = nodeIndexes.map { DerivationNode.fromIndex(it.toLong()) }
|
||||
return DerivationPath(rawPath, nodes)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
package com.tangem.tap.domain.userWalletList.utils.json
|
||||
|
||||
import com.squareup.moshi.FromJson
|
||||
import com.squareup.moshi.JsonAdapter
|
||||
import com.squareup.moshi.JsonReader
|
||||
import com.squareup.moshi.JsonWriter
|
||||
import com.squareup.moshi.ToJson
|
||||
import com.tangem.common.extensions.hexToBytes
|
||||
import com.tangem.common.extensions.toHexString
|
||||
import com.tangem.crypto.hdWallet.DerivationPath
|
||||
import com.tangem.crypto.hdWallet.bip32.ExtendedPublicKey
|
||||
import com.tangem.operations.derivation.ExtendedPublicKeysMap
|
||||
|
||||
internal class ExtendedPublicKeysMapAdapter {
|
||||
@ToJson
|
||||
fun toJson(
|
||||
writer: JsonWriter,
|
||||
src: ExtendedPublicKeysMap,
|
||||
mapAdapter: JsonAdapter<Map<String, String>>,
|
||||
derivationPathAdapter: JsonAdapter<DerivationPath>,
|
||||
extendedPublicKeyAdapter: JsonAdapter<ExtendedPublicKey>,
|
||||
) {
|
||||
val jsonMap = mutableMapOf<String, String>()
|
||||
|
||||
src.forEach { (derivationPath, extendedPublicKey) ->
|
||||
val derivationPathJson = derivationPathAdapter.toJson(derivationPath)
|
||||
val derivationPathEncoded = derivationPathJson.encodeToByteArray().toHexString()
|
||||
val extendedPublicKeyJson = extendedPublicKeyAdapter.toJson(extendedPublicKey)
|
||||
|
||||
jsonMap[derivationPathEncoded] = extendedPublicKeyJson
|
||||
}
|
||||
|
||||
mapAdapter.toJson(writer, jsonMap)
|
||||
}
|
||||
|
||||
@FromJson
|
||||
fun fromJson(
|
||||
reader: JsonReader,
|
||||
mapAdapter: JsonAdapter<Map<String, String>>,
|
||||
derivationPathAdapter: JsonAdapter<DerivationPath>,
|
||||
extendedPublicKeyAdapter: JsonAdapter<ExtendedPublicKey>,
|
||||
): ExtendedPublicKeysMap {
|
||||
val map = mutableMapOf<DerivationPath, ExtendedPublicKey>()
|
||||
|
||||
mapAdapter.fromJson(reader)?.forEach { (derivationPathEncoded, extendedPublicKeyJson) ->
|
||||
val derivationPathJson = derivationPathEncoded.hexToBytes().decodeToString()
|
||||
val derivationPath = derivationPathAdapter.fromJson(derivationPathJson)
|
||||
val extendedPublicKey = extendedPublicKeyAdapter.fromJson(extendedPublicKeyJson)
|
||||
|
||||
if (derivationPath != null && extendedPublicKey != null) {
|
||||
map[derivationPath] = extendedPublicKey
|
||||
}
|
||||
}
|
||||
|
||||
return ExtendedPublicKeysMap(map)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
package com.tangem.tap.domain.userWalletList.utils.json
|
||||
|
||||
import com.squareup.moshi.FromJson
|
||||
import com.squareup.moshi.JsonAdapter
|
||||
import com.squareup.moshi.JsonReader
|
||||
import com.squareup.moshi.JsonWriter
|
||||
import com.squareup.moshi.ToJson
|
||||
import com.tangem.common.extensions.ByteArrayKey
|
||||
import com.tangem.operations.derivation.ExtendedPublicKeysMap
|
||||
|
||||
internal class ScanResponseDerivedKeysMapAdapter {
|
||||
@ToJson
|
||||
fun toJson(
|
||||
writer: JsonWriter,
|
||||
src: Map<ByteArrayKey, ExtendedPublicKeysMap>,
|
||||
mapAdapter: JsonAdapter<Map<String, String>>,
|
||||
byteArrayKeyAdapter: JsonAdapter<ByteArrayKey>,
|
||||
extendedPublicKeysMapAdapter: JsonAdapter<ExtendedPublicKeysMap>,
|
||||
) {
|
||||
val jsonMap = mutableMapOf<String, String>()
|
||||
|
||||
src.forEach { (key, extendedPublicKeysMap) ->
|
||||
val keyJson = byteArrayKeyAdapter.toJson(key)
|
||||
val extendedPublicKeysMapJson = extendedPublicKeysMapAdapter.toJson(extendedPublicKeysMap)
|
||||
|
||||
jsonMap[keyJson] = extendedPublicKeysMapJson
|
||||
}
|
||||
|
||||
mapAdapter.toJson(writer, jsonMap)
|
||||
}
|
||||
|
||||
@FromJson
|
||||
fun fromJson(
|
||||
reader: JsonReader,
|
||||
mapAdapter: JsonAdapter<Map<String, String>>,
|
||||
byteArrayKeyAdapter: JsonAdapter<ByteArrayKey>,
|
||||
extendedPublicKeysMapAdapter: JsonAdapter<ExtendedPublicKeysMap>,
|
||||
): Map<ByteArrayKey, ExtendedPublicKeysMap> {
|
||||
val map = mutableMapOf<ByteArrayKey, ExtendedPublicKeysMap>()
|
||||
|
||||
mapAdapter.fromJson(reader)?.forEach { (keyJson, extendedPublicKeysMapJson) ->
|
||||
val key = byteArrayKeyAdapter.fromJson(keyJson)
|
||||
val extendedPublicKeysMap = extendedPublicKeysMapAdapter.fromJson(extendedPublicKeysMapJson)
|
||||
|
||||
if (key != null && extendedPublicKeysMap != null) {
|
||||
map[key] = extendedPublicKeysMap
|
||||
}
|
||||
}
|
||||
|
||||
return map
|
||||
}
|
||||
}
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
package com.tangem.tap.domain.userWalletList.utils.json
|
||||
|
||||
import com.squareup.moshi.FromJson
|
||||
import com.squareup.moshi.JsonAdapter
|
||||
import com.squareup.moshi.JsonReader
|
||||
import com.squareup.moshi.JsonWriter
|
||||
import com.squareup.moshi.ToJson
|
||||
import com.tangem.common.extensions.hexToBytes
|
||||
import com.tangem.common.extensions.toHexString
|
||||
import com.tangem.crypto.hdWallet.DerivationPath
|
||||
import com.tangem.crypto.hdWallet.bip32.ExtendedPublicKey
|
||||
|
||||
internal class WalletDerivedKeysMapAdapter {
|
||||
@ToJson
|
||||
fun toJson(
|
||||
writer: JsonWriter,
|
||||
src: Map<DerivationPath, ExtendedPublicKey>,
|
||||
mapAdapter: JsonAdapter<Map<String, String>>,
|
||||
derivationPathAdapter: JsonAdapter<DerivationPath>,
|
||||
extendedPublicKeyAdapter: JsonAdapter<ExtendedPublicKey>,
|
||||
) {
|
||||
val jsonMap = mutableMapOf<String, String>()
|
||||
|
||||
src.forEach { (derivationPath, extendedPublicKey) ->
|
||||
val derivationPathJson = derivationPathAdapter.toJson(derivationPath)
|
||||
val derivationPathEncoded = derivationPathJson.encodeToByteArray().toHexString()
|
||||
val extendedPublicKeyJson = extendedPublicKeyAdapter.toJson(extendedPublicKey)
|
||||
|
||||
jsonMap[derivationPathEncoded] = extendedPublicKeyJson
|
||||
}
|
||||
|
||||
mapAdapter.toJson(writer, jsonMap)
|
||||
}
|
||||
|
||||
@FromJson
|
||||
fun fromJson(
|
||||
reader: JsonReader,
|
||||
mapAdapter: JsonAdapter<Map<String, String>>,
|
||||
derivationPathAdapter: JsonAdapter<DerivationPath>,
|
||||
extendedPublicKeyAdapter: JsonAdapter<ExtendedPublicKey>,
|
||||
): Map<DerivationPath, ExtendedPublicKey> {
|
||||
val map = mutableMapOf<DerivationPath, ExtendedPublicKey>()
|
||||
|
||||
mapAdapter.fromJson(reader)?.forEach { (derivationPathEncoded, extendedPublicKeyJson) ->
|
||||
val derivationPathJson = derivationPathEncoded.hexToBytes().decodeToString()
|
||||
val derivationPath = derivationPathAdapter.fromJson(derivationPathJson)
|
||||
val extendedPublicKey = extendedPublicKeyAdapter.fromJson(extendedPublicKeyJson)
|
||||
|
||||
if (derivationPath != null && extendedPublicKey != null) {
|
||||
map[derivationPath] = extendedPublicKey
|
||||
}
|
||||
}
|
||||
|
||||
return map
|
||||
}
|
||||
}
|
||||
|
|
@ -267,7 +267,7 @@ internal class DefaultLegacyWalletConnectRepository(
|
|||
)
|
||||
}
|
||||
|
||||
override fun approve(userNamespaces: Map<NetworkNamespace, List<Account>>) {
|
||||
override fun approve(userNamespaces: Map<NetworkNamespace, List<Account>>, blockchainNames: List<String>) {
|
||||
val sessionProposal: Wallet.Model.SessionProposal = requireNotNull(this.sessionProposal)
|
||||
|
||||
val userChains = userNamespaces.flatMap { namespace ->
|
||||
|
|
@ -311,6 +311,7 @@ internal class DefaultLegacyWalletConnectRepository(
|
|||
WalletConnect.NewSessionEstablished(
|
||||
dAppName = sessionProposal.name,
|
||||
dAppUrl = sessionProposal.url,
|
||||
blockchainNames = blockchainNames,
|
||||
),
|
||||
)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package com.tangem.tap.domain.walletconnect2.di
|
|||
import android.app.Application
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
|
||||
import com.tangem.core.configtoggle.feature.FeatureTogglesManager
|
||||
import com.tangem.datasource.di.SdkMoshi
|
||||
import com.tangem.datasource.files.FileReader
|
||||
import com.tangem.domain.tokens.repository.CurrenciesRepository
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ interface LegacyWalletConnectRepository {
|
|||
|
||||
fun disconnect(topic: String)
|
||||
|
||||
fun approve(userNamespaces: Map<NetworkNamespace, List<Account>>)
|
||||
fun approve(userNamespaces: Map<NetworkNamespace, List<Account>>, blockchainNames: List<String>)
|
||||
|
||||
fun reject()
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.tap.domain.walletconnect2.domain
|
||||
|
||||
import arrow.core.flatten
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchainsdk.utils.toNetworkId
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
|
|
@ -236,8 +237,12 @@ class WalletConnectInteractor(
|
|||
blockchainHelper.getNamespaceFromFullChainIdOrNull(account.chainId)
|
||||
?.let { NetworkNamespace(it) }
|
||||
}.filterNotNull()
|
||||
|
||||
val blockchainNames = blockchainHelper.chainIdsToBlockchains(userNamespaces.values.flatten().map { it.chainId })
|
||||
.map { it.fullName }
|
||||
walletConnectRepository.approve(
|
||||
userNamespaces = userNamespaces,
|
||||
blockchainNames = blockchainNames,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.tap.domain.walletconnect2.toggles
|
||||
|
||||
import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
|
||||
import com.tangem.core.configtoggle.feature.FeatureTogglesManager
|
||||
|
||||
internal class WalletConnectFeatureToggles(
|
||||
private val featureTogglesManager: FeatureTogglesManager,
|
||||
|
|
|
|||
|
|
@ -37,5 +37,7 @@ sealed class WalletConnectAction : Action {
|
|||
data class PerformRequestedAction(val sessionRequest: WcPreparedRequest) : WalletConnectAction()
|
||||
|
||||
data class PairConnectErrorAction(val throwable: Throwable) : WalletConnectAction()
|
||||
|
||||
data object UnsupportedDappRequest : WalletConnectAction()
|
||||
//endregion WalletConnect 2.0
|
||||
}
|
||||
|
|
@ -78,6 +78,12 @@ class WalletConnectMiddleware {
|
|||
val index = action.wcUri.indexOf("@")
|
||||
when (action.wcUri[index + 1]) {
|
||||
'2' -> walletConnectRepository.pair(uri = action.wcUri)
|
||||
'1' -> {
|
||||
store.dispatchOnMain(WalletConnectAction.UnsupportedDappRequest)
|
||||
store.dispatchOnMain(
|
||||
GlobalAction.ShowDialog(WalletConnectDialog.UnsupportedWcVersion),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
is WalletConnectAction.RejectRequest -> {
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ object WalletConnectReducer {
|
|||
is WalletConnectAction.SessionEstablished,
|
||||
is WalletConnectAction.SessionRejected,
|
||||
is WalletConnectAction.PairConnectErrorAction,
|
||||
is WalletConnectAction.UnsupportedDappRequest,
|
||||
-> state.copy(loading = false)
|
||||
is WalletConnectAction.SessionListUpdated -> state.copy(
|
||||
wc2Sessions = action.sessions,
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ data class WalletForSession(
|
|||
}
|
||||
|
||||
sealed class WalletConnectDialog : StateDialog {
|
||||
data object UnsupportedWcVersion : WalletConnectDialog()
|
||||
data class ClipboardOrScanQr(val clipboardUri: String) : WalletConnectDialog()
|
||||
data object UnsupportedCard : WalletConnectDialog()
|
||||
data class UnsupportedNetwork(val networks: List<String>? = null) : WalletConnectDialog()
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.tap.features.home.featuretoggles
|
||||
|
||||
import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
|
||||
import com.tangem.core.configtoggle.feature.FeatureTogglesManager
|
||||
import javax.inject.Inject
|
||||
|
||||
class HomeFeatureToggles @Inject constructor(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
package com.tangem.tap.features.intentHandler.handlers
|
||||
|
||||
import android.content.Intent
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.tap.common.analytics.events.Push
|
||||
import com.tangem.tap.features.intentHandler.IntentHandler
|
||||
|
||||
internal class OnPushClickedIntentHandler(val analyticsEventHandler: AnalyticsEventHandler) : IntentHandler {
|
||||
|
||||
override fun handleIntent(intent: Intent?, isFromForeground: Boolean): Boolean {
|
||||
val fromPush = intent?.extras?.getBoolean(IS_OPENED_FROM_PUSH) ?: false
|
||||
|
||||
return if (fromPush) {
|
||||
analyticsEventHandler.send(Push.PushNotificationOpened)
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val IS_OPENED_FROM_PUSH = "IS_OPENED_FROM_PUSH"
|
||||
}
|
||||
}
|
||||
|
|
@ -17,7 +17,6 @@ import com.tangem.domain.settings.IncrementAppLaunchCounterUseCase
|
|||
import com.tangem.domain.settings.usercountry.FetchUserCountryUseCase
|
||||
import com.tangem.domain.staking.FetchStakingTokensUseCase
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.features.staking.api.featuretoggles.StakingFeatureToggles
|
||||
import com.tangem.tap.common.extensions.setContext
|
||||
import com.tangem.tap.features.home.featuretoggles.HomeFeatureToggles
|
||||
import com.tangem.tap.features.main.model.MainScreenState
|
||||
|
|
@ -40,7 +39,6 @@ internal class MainViewModel @Inject constructor(
|
|||
private val blockchainSDKFactory: BlockchainSDKFactory,
|
||||
private val userWalletsListManager: UserWalletsListManager,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
stakingFeatureToggles: StakingFeatureToggles,
|
||||
private val fetchStakingTokensUseCase: FetchStakingTokensUseCase,
|
||||
private val apiConfigsManager: ApiConfigsManager,
|
||||
homeFeatureToggles: HomeFeatureToggles,
|
||||
|
|
@ -78,9 +76,7 @@ internal class MainViewModel @Inject constructor(
|
|||
displayBalancesHidingStatusToast()
|
||||
displayHiddenBalancesModalNotification()
|
||||
|
||||
if (stakingFeatureToggles.isStakingEnabled) {
|
||||
fetchStakingTokens()
|
||||
}
|
||||
fetchStakingTokens()
|
||||
|
||||
deleteDeprecatedLogsUseCase()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import com.tangem.domain.models.scan.ScanResponse
|
|||
import com.tangem.domain.settings.usercountry.models.UserCountry
|
||||
import com.tangem.domain.wallets.builder.UserWalletBuilder
|
||||
import com.tangem.domain.wallets.builder.UserWalletIdBuilder
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.tap.common.analytics.converters.ParamCardCurrencyConverter
|
||||
import com.tangem.tap.common.analytics.events.AnalyticsParam
|
||||
import com.tangem.tap.common.analytics.events.Onboarding
|
||||
|
|
@ -23,8 +24,8 @@ import com.tangem.tap.common.extensions.*
|
|||
import com.tangem.tap.common.redux.AppDialog
|
||||
import com.tangem.tap.common.redux.global.GlobalState
|
||||
import com.tangem.tap.features.demo.DemoHelper
|
||||
import com.tangem.tap.features.onboarding.products.wallet.redux.OnboardingWalletAction
|
||||
import com.tangem.tap.features.home.RUSSIA_COUNTRY_CODE
|
||||
import com.tangem.tap.features.onboarding.products.wallet.redux.OnboardingWalletAction
|
||||
import com.tangem.tap.features.saveWallet.redux.SaveWalletAction
|
||||
import com.tangem.tap.mainScope
|
||||
import com.tangem.tap.proxy.redux.DaggerGraphState
|
||||
|
|
@ -67,7 +68,10 @@ object OnboardingHelper {
|
|||
|
||||
fun whereToNavigate(scanResponse: ScanResponse): AppRoute {
|
||||
if (store.inject(DaggerGraphState::onboardingV2FeatureToggles).isOnboardingV2Enabled) {
|
||||
return AppRoute.Onboarding(scanResponse)
|
||||
return AppRoute.Onboarding(
|
||||
scanResponse = scanResponse,
|
||||
startFromBackup = false,
|
||||
)
|
||||
}
|
||||
|
||||
return when (val type = scanResponse.productType) {
|
||||
|
|
@ -88,6 +92,7 @@ object OnboardingHelper {
|
|||
}
|
||||
|
||||
fun saveWallet(
|
||||
alreadyCreatedWallet: UserWallet?,
|
||||
scanResponse: ScanResponse,
|
||||
accessCode: String? = null,
|
||||
backupCardsIds: List<String>? = null,
|
||||
|
|
@ -117,7 +122,7 @@ object OnboardingHelper {
|
|||
// When should not save user wallets but device has biometry and save wallet screen has not been shown,
|
||||
// then open save wallet screen
|
||||
tangemSdkManager.checkCanUseBiometry() && settingsRepository.shouldShowSaveUserWalletScreen() -> {
|
||||
proceedWithScanResponse(scanResponse, backupCardsIds, hasBackupError)
|
||||
proceedWithScanResponse(scanResponse, backupCardsIds, hasBackupError, alreadyCreatedWallet)
|
||||
|
||||
delay(timeMillis = 1_200)
|
||||
|
||||
|
|
@ -131,7 +136,7 @@ object OnboardingHelper {
|
|||
}
|
||||
// If device has no biometry and save wallet screen has been shown, then go through old scenario
|
||||
else -> {
|
||||
proceedWithScanResponse(scanResponse, backupCardsIds, hasBackupError)
|
||||
proceedWithScanResponse(scanResponse, backupCardsIds, hasBackupError, alreadyCreatedWallet)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -207,7 +212,9 @@ object OnboardingHelper {
|
|||
|
||||
fun handleTopUpAction(walletManager: WalletManager, scanResponse: ScanResponse, globalState: GlobalState) {
|
||||
val blockchain = walletManager.wallet.blockchain
|
||||
val cryptoCurrency = CryptoCurrencyFactory().createCoin(
|
||||
val excludedBlockchains = store.inject(DaggerGraphState::excludedBlockchains)
|
||||
|
||||
val cryptoCurrency = CryptoCurrencyFactory(excludedBlockchains).createCoin(
|
||||
blockchain = blockchain,
|
||||
extraDerivationPath = null,
|
||||
scanResponse = scanResponse,
|
||||
|
|
@ -242,9 +249,10 @@ object OnboardingHelper {
|
|||
scanResponse: ScanResponse,
|
||||
backupCardsIds: List<String>?,
|
||||
hasBackupError: Boolean,
|
||||
alreadyCreatedWallet: UserWallet? = null,
|
||||
) {
|
||||
val walletNameGenerateUseCase = store.inject(DaggerGraphState::generateWalletNameUseCase)
|
||||
val userWallet = UserWalletBuilder(scanResponse, walletNameGenerateUseCase)
|
||||
val userWallet = alreadyCreatedWallet ?: UserWalletBuilder(scanResponse, walletNameGenerateUseCase)
|
||||
.hasBackupError(hasBackupError)
|
||||
.backupCardsIds(backupCardsIds?.toSet())
|
||||
.build()
|
||||
|
|
|
|||
|
|
@ -197,11 +197,11 @@ private fun handleWalletAction(action: Action) {
|
|||
}
|
||||
}
|
||||
|
||||
private fun handleFinishBackup(scanResponse: ScanResponse) {
|
||||
private fun handleFinishBackup(scanResponse: ScanResponse, userWallet: UserWallet? = null) {
|
||||
val backupState = store.state.onboardingWalletState.backupState
|
||||
val updatedScanResponse = updateScanResponseAfterBackup(scanResponse, backupState)
|
||||
|
||||
val userWalletId = UserWalletIdBuilder.scanResponse(scanResponse).build()
|
||||
val userWalletId = userWallet?.walletId ?: UserWalletIdBuilder.scanResponse(scanResponse).build()
|
||||
if (backupState.hasRing && userWalletId != null) {
|
||||
scope.launch {
|
||||
store.inject(DaggerGraphState::walletsRepository).setHasWalletsWithRing(userWalletId = userWalletId)
|
||||
|
|
@ -209,6 +209,7 @@ private fun handleFinishBackup(scanResponse: ScanResponse) {
|
|||
}
|
||||
|
||||
OnboardingHelper.saveWallet(
|
||||
alreadyCreatedWallet = userWallet,
|
||||
scanResponse = updatedScanResponse,
|
||||
accessCode = backupState.accessCode,
|
||||
backupCardsIds = backupState.backupCardIds,
|
||||
|
|
@ -679,7 +680,7 @@ private fun handleBackupAction(appState: () -> AppState?, action: BackupAction)
|
|||
Analytics.send(Onboarding.Finished())
|
||||
|
||||
store.state.globalState.onboardingState.onboardingManager?.finishActivation(notActivatedCardIds)
|
||||
handleFinishBackup(requireNotNull(scanResponse))
|
||||
handleFinishBackup(requireNotNull(scanResponse), userWallet)
|
||||
delay(1000)
|
||||
store.dispatchWithMain(BackupAction.BackupFinished(userWalletId = userWallet?.walletId))
|
||||
}
|
||||
|
|
@ -740,6 +741,7 @@ private suspend fun createUserWallet(scanResponse: ScanResponse, backupState: Ba
|
|||
return requireNotNull(
|
||||
value = UserWalletBuilder(scanResponse, walletNameGenerateUseCase)
|
||||
.backupCardsIds(backupState.backupCardIds.toSet())
|
||||
.hasBackupError(backupState.hasBackupError)
|
||||
.build(),
|
||||
lazyMessage = { "User wallet not created" },
|
||||
)
|
||||
|
|
|
|||
|
|
@ -272,6 +272,7 @@ class OnboardingWalletFragment :
|
|||
onboardingManageTokensComponent = onboardingManageTokensComponentFactory.create(
|
||||
context = onboardingComponentContext,
|
||||
params = OnboardingManageTokensComponent.Params(userWalletId = userWalletId),
|
||||
onDone = {},
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,11 +5,11 @@ import com.tangem.common.core.TangemSdkError
|
|||
import com.tangem.common.extensions.guard
|
||||
import com.tangem.common.routing.AppRoute
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.core.analytics.models.event.MainScreenAnalyticsEvent
|
||||
import com.tangem.domain.wallets.builder.UserWalletBuilder
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
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
|
||||
import com.tangem.tap.common.extensions.dispatchNavigationAction
|
||||
import com.tangem.tap.common.extensions.dispatchWithMain
|
||||
|
|
@ -110,7 +110,11 @@ internal class SaveWalletMiddleware {
|
|||
// TODO: Remove after onboarding refactoring
|
||||
Analytics.send(Onboarding.EnableBiometrics(AnalyticsParam.OnOffState.On))
|
||||
} else {
|
||||
Analytics.send(MainScreen.EnableBiometrics(AnalyticsParam.OnOffState.On))
|
||||
Analytics.send(
|
||||
MainScreenAnalyticsEvent.EnableBiometrics(
|
||||
state = com.tangem.core.analytics.models.AnalyticsParam.OnOffState.On,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -148,7 +152,11 @@ internal class SaveWalletMiddleware {
|
|||
// TODO: Remove after onboarding refactoring
|
||||
Analytics.send(Onboarding.EnableBiometrics(AnalyticsParam.OnOffState.Off))
|
||||
} else {
|
||||
Analytics.send(MainScreen.EnableBiometrics(AnalyticsParam.OnOffState.Off))
|
||||
Analytics.send(
|
||||
MainScreenAnalyticsEvent.EnableBiometrics(
|
||||
com.tangem.core.analytics.models.AnalyticsParam.OnOffState.Off,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -55,11 +55,15 @@ object TradeCryptoMiddleware {
|
|||
|
||||
private fun proceedBuyAction(state: () -> AppState?, action: TradeCryptoAction.Buy) {
|
||||
val isOnrampEnabled = store.inject(DaggerGraphState::onrampFeatureToggles).isFeatureEnabled
|
||||
if (isOnrampEnabled) proceedWithOnramp() else proceedWithLegacyBuyAction(state, action)
|
||||
if (isOnrampEnabled) {
|
||||
proceedWithOnramp(action.userWallet.walletId, action.cryptoCurrencyStatus.currency)
|
||||
} else {
|
||||
proceedWithLegacyBuyAction(state, action)
|
||||
}
|
||||
}
|
||||
|
||||
private fun proceedWithOnramp() {
|
||||
store.dispatchNavigationAction { push(AppRoute.Onramp) }
|
||||
private fun proceedWithOnramp(userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency) {
|
||||
store.dispatchNavigationAction { push(AppRoute.Onramp(userWalletId = userWalletId, currency = cryptoCurrency)) }
|
||||
}
|
||||
|
||||
private fun proceedWithLegacyBuyAction(state: () -> AppState?, action: TradeCryptoAction.Buy) {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.tangem.tap.network.exchangeServices
|
|||
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.Token
|
||||
import com.tangem.blockchainsdk.utils.ExcludedBlockchains
|
||||
import com.tangem.data.common.currency.CryptoCurrencyFactory
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.tap.common.extensions.inject
|
||||
|
|
@ -10,9 +11,11 @@ import com.tangem.tap.proxy.redux.DaggerGraphState
|
|||
import com.tangem.tap.store
|
||||
import com.tangem.utils.converter.TwoWayConverter
|
||||
|
||||
internal class CryptoCurrencyConverter : TwoWayConverter<Currency, CryptoCurrency> {
|
||||
internal class CryptoCurrencyConverter(
|
||||
private val excludedBlockchains: ExcludedBlockchains,
|
||||
) : TwoWayConverter<Currency, CryptoCurrency> {
|
||||
|
||||
private val cryptoCurrencyFactory by lazy { CryptoCurrencyFactory() }
|
||||
private val cryptoCurrencyFactory by lazy { CryptoCurrencyFactory(excludedBlockchains) }
|
||||
|
||||
override fun convert(value: Currency): CryptoCurrency {
|
||||
return when (value) {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ import com.tangem.blockchain.common.Blockchain
|
|||
import com.tangem.blockchain.common.transaction.TransactionFee
|
||||
import com.tangem.blockchain.extensions.Result
|
||||
import com.tangem.domain.common.TapWorkarounds.isTangemTwins
|
||||
import com.tangem.domain.core.utils.lceContent
|
||||
import com.tangem.domain.core.utils.lceLoading
|
||||
import com.tangem.domain.models.scan.CardDTO
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
|
|
@ -19,6 +21,8 @@ import com.tangem.tap.domain.model.Currency
|
|||
import com.tangem.tap.features.demo.isDemoCard
|
||||
import com.tangem.tap.proxy.redux.DaggerGraphState
|
||||
import com.tangem.tap.store
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import java.math.BigDecimal
|
||||
|
||||
/**
|
||||
|
|
@ -30,9 +34,19 @@ class CurrencyExchangeManager(
|
|||
private val primaryRules: ExchangeRules,
|
||||
) : ExchangeService {
|
||||
|
||||
override val initializationStatus: StateFlow<ExchangeServiceInitializationStatus>
|
||||
get() = _initializationStatus
|
||||
|
||||
private val _initializationStatus: MutableStateFlow<ExchangeServiceInitializationStatus> =
|
||||
MutableStateFlow(value = lceLoading())
|
||||
|
||||
override suspend fun update() {
|
||||
_initializationStatus.value = lceLoading()
|
||||
|
||||
buyService.update()
|
||||
sellService.update()
|
||||
|
||||
_initializationStatus.value = lceContent()
|
||||
}
|
||||
|
||||
override fun isBuyAllowed(): Boolean = primaryRules.isBuyAllowed() && buyService.isBuyAllowed()
|
||||
|
|
|
|||
|
|
@ -1,22 +1,128 @@
|
|||
package com.tangem.tap.network.exchangeServices
|
||||
|
||||
import com.tangem.blockchainsdk.utils.ExcludedBlockchains
|
||||
import com.tangem.datasource.api.express.models.TangemExpressValues.EMPTY_CONTRACT_ADDRESS_VALUE
|
||||
import com.tangem.datasource.exchangeservice.swap.SwapServiceLoader
|
||||
import com.tangem.domain.exchange.RampStateManager
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.tokens.GetNetworkCoinStatusUseCase
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.tokens.model.ScenarioUnavailabilityReason
|
||||
import com.tangem.domain.tokens.repository.CurrenciesRepository
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.utils.Provider
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.isNullOrZero
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class DefaultRampManager(private val exchangeService: ExchangeService?) : RampStateManager {
|
||||
@Suppress("LongParameterList")
|
||||
internal class DefaultRampManager(
|
||||
private val exchangeService: ExchangeService?,
|
||||
private val buyService: Provider<ExchangeService>,
|
||||
private val sellService: Provider<ExchangeService>,
|
||||
private val swapServiceLoader: SwapServiceLoader,
|
||||
private val currenciesRepository: CurrenciesRepository,
|
||||
private val getNetworkCoinStatusUseCase: GetNetworkCoinStatusUseCase,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
excludedBlockchains: ExcludedBlockchains,
|
||||
) : RampStateManager {
|
||||
|
||||
private val cryptoCurrencyConverter = CryptoCurrencyConverter()
|
||||
override fun availableForBuy(scanResponse: ScanResponse, cryptoCurrency: CryptoCurrency): Boolean {
|
||||
return exchangeService?.availableForBuy(
|
||||
scanResponse,
|
||||
currency = cryptoCurrencyConverter.convertBack(cryptoCurrency),
|
||||
) ?: false
|
||||
}
|
||||
private val cryptoCurrencyConverter = CryptoCurrencyConverter(excludedBlockchains)
|
||||
|
||||
override fun availableForSell(cryptoCurrency: CryptoCurrency): Boolean {
|
||||
override fun isSellSupportedByService(cryptoCurrency: CryptoCurrency): Boolean {
|
||||
return exchangeService?.availableForSell(
|
||||
currency = cryptoCurrencyConverter.convertBack(cryptoCurrency),
|
||||
) ?: false
|
||||
}
|
||||
|
||||
override fun availableForBuy(scanResponse: ScanResponse, cryptoCurrency: CryptoCurrency): Boolean {
|
||||
return exchangeService?.availableForBuy(
|
||||
scanResponse = scanResponse,
|
||||
currency = cryptoCurrencyConverter.convertBack(cryptoCurrency),
|
||||
) ?: false
|
||||
}
|
||||
|
||||
override suspend fun availableForSell(userWalletId: UserWalletId, status: CryptoCurrencyStatus): Boolean {
|
||||
val sellSupportedByService = isSellSupportedByService(cryptoCurrency = status.currency)
|
||||
|
||||
if (!sellSupportedByService) return false
|
||||
|
||||
val reason = getSendUnavailabilityReason(userWalletId, status)
|
||||
|
||||
return reason == ScenarioUnavailabilityReason.None
|
||||
}
|
||||
|
||||
override suspend fun availableForSwap(userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency): Boolean {
|
||||
return getExchangeableFlag(userWalletId, cryptoCurrency) && !cryptoCurrency.isCustom
|
||||
}
|
||||
|
||||
override fun getBuyInitializationStatus(): Flow<ExchangeServiceInitializationStatus> {
|
||||
return buyService.invoke().initializationStatus
|
||||
}
|
||||
|
||||
override suspend fun fetchBuyServiceData() {
|
||||
withContext(dispatchers.io) {
|
||||
buyService.invoke().update()
|
||||
}
|
||||
}
|
||||
|
||||
override fun getSellInitializationStatus(): Flow<ExchangeServiceInitializationStatus> {
|
||||
return sellService.invoke().initializationStatus
|
||||
}
|
||||
|
||||
override suspend fun fetchSellServiceData() {
|
||||
withContext(dispatchers.io) {
|
||||
sellService.invoke().update()
|
||||
}
|
||||
}
|
||||
|
||||
override fun getSwapInitializationStatus(userWalletId: UserWalletId): Flow<ExchangeServiceInitializationStatus> {
|
||||
return swapServiceLoader.getInitializationStatus(userWalletId)
|
||||
}
|
||||
|
||||
private suspend fun getExchangeableFlag(userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency): Boolean {
|
||||
return withContext(dispatchers.io) {
|
||||
val contractAddress = (cryptoCurrency as? CryptoCurrency.Token)?.contractAddress
|
||||
?: EMPTY_CONTRACT_ADDRESS_VALUE
|
||||
|
||||
val asset = swapServiceLoader.getInitializationStatus(userWalletId).value.getOrNull()?.find {
|
||||
it.network == cryptoCurrency.network.backendId &&
|
||||
it.contractAddress.equals(contractAddress, ignoreCase = true)
|
||||
}
|
||||
|
||||
asset?.exchangeAvailable ?: false
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun getSendUnavailabilityReason(
|
||||
userWalletId: UserWalletId,
|
||||
cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
): ScenarioUnavailabilityReason {
|
||||
val coinStatus = getNetworkCoinStatusUseCase.invokeSync(
|
||||
userWalletId = userWalletId,
|
||||
networkId = cryptoCurrencyStatus.currency.network.id,
|
||||
derivationPath = cryptoCurrencyStatus.currency.network.derivationPath,
|
||||
isSingleWalletWithTokens = false,
|
||||
).getOrNull()
|
||||
|
||||
return when {
|
||||
cryptoCurrencyStatus.value.amount.isNullOrZero() -> {
|
||||
ScenarioUnavailabilityReason.EmptyBalance(ScenarioUnavailabilityReason.WithdrawalScenario.SEND)
|
||||
}
|
||||
currenciesRepository.isSendBlockedByPendingTransactions(
|
||||
cryptoCurrencyStatus = cryptoCurrencyStatus,
|
||||
coinStatus = coinStatus,
|
||||
) -> {
|
||||
ScenarioUnavailabilityReason.PendingTransaction(
|
||||
withdrawalScenario = ScenarioUnavailabilityReason.WithdrawalScenario.SEND,
|
||||
networkName = coinStatus?.currency?.network?.name.orEmpty(),
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
ScenarioUnavailabilityReason.None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,14 @@
|
|||
package com.tangem.tap.network.exchangeServices
|
||||
|
||||
import com.tangem.domain.core.lce.Lce
|
||||
import com.tangem.domain.core.utils.lceLoading
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.tap.domain.model.Currency
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
||||
typealias ExchangeServiceInitializationStatus = Lce<Throwable, Any>
|
||||
|
||||
interface Exchanger {
|
||||
fun isBuyAllowed(): Boolean
|
||||
|
|
@ -12,10 +18,17 @@ interface Exchanger {
|
|||
}
|
||||
|
||||
interface ExchangeService : Exchanger, ExchangeUrlBuilder {
|
||||
|
||||
val initializationStatus: StateFlow<ExchangeServiceInitializationStatus>
|
||||
|
||||
suspend fun update()
|
||||
|
||||
companion object {
|
||||
fun dummy(): ExchangeService = object : ExchangeService {
|
||||
|
||||
override val initializationStatus: StateFlow<ExchangeServiceInitializationStatus> =
|
||||
MutableStateFlow(value = lceLoading())
|
||||
|
||||
override suspend fun update() {}
|
||||
override fun isBuyAllowed(): Boolean = false
|
||||
override fun isSellAllowed(): Boolean = false
|
||||
|
|
|
|||
|
|
@ -138,6 +138,8 @@ internal val Blockchain.mercuryoNetwork: String?
|
|||
Blockchain.CasperTestnet -> null
|
||||
Blockchain.Core -> null
|
||||
Blockchain.CoreTestnet -> null
|
||||
Blockchain.Chiliz -> null
|
||||
Blockchain.ChilizTestnet -> null
|
||||
Blockchain.Unknown -> null
|
||||
Blockchain.Xodex -> null
|
||||
Blockchain.Canxium -> null
|
||||
|
|
|
|||
|
|
@ -6,12 +6,19 @@ import com.tangem.common.extensions.calculateSha512
|
|||
import com.tangem.common.extensions.toHexString
|
||||
import com.tangem.common.services.Result
|
||||
import com.tangem.common.services.performRequest
|
||||
import com.tangem.domain.core.utils.lceContent
|
||||
import com.tangem.domain.core.utils.lceError
|
||||
import com.tangem.domain.core.utils.lceLoading
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.tap.domain.model.Currency
|
||||
import com.tangem.tap.network.exchangeServices.CurrencyExchangeManager
|
||||
import com.tangem.tap.network.exchangeServices.ExchangeService
|
||||
import com.tangem.tap.network.exchangeServices.ExchangeServiceInitializationStatus
|
||||
import com.tangem.tap.network.exchangeServices.ExchangeUrlBuilder
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import timber.log.Timber
|
||||
import java.util.concurrent.CopyOnWriteArrayList
|
||||
|
||||
/**
|
||||
|
|
@ -19,10 +26,34 @@ import java.util.concurrent.CopyOnWriteArrayList
|
|||
*/
|
||||
internal class MercuryoService(private val environment: MercuryoEnvironment) : ExchangeService {
|
||||
|
||||
override val initializationStatus: StateFlow<ExchangeServiceInitializationStatus>
|
||||
get() = _initializationStatus
|
||||
|
||||
private val _initializationStatus: MutableStateFlow<ExchangeServiceInitializationStatus> =
|
||||
MutableStateFlow(value = lceLoading())
|
||||
|
||||
private val api: MercuryoApi = environment.mercuryoApi
|
||||
|
||||
private val availableMercuryoCurrencies = CopyOnWriteArrayList<MercuryoCurrenciesResponse.MercuryoCryptoCurrency>()
|
||||
|
||||
override suspend fun update() {
|
||||
Timber.i("Start updating")
|
||||
_initializationStatus.value = lceLoading()
|
||||
|
||||
val result = performRequest { api.currencies(environment.apiVersion) }
|
||||
when {
|
||||
result is Result.Success && result.data.status == RESPONSE_SUCCESS_STATUS_CODE -> {
|
||||
handleSuccessfullyUpdatedData(data = result.data.data)
|
||||
}
|
||||
result is Result.Failure -> {
|
||||
availableMercuryoCurrencies.clear()
|
||||
|
||||
Timber.e("Failed to load currencies", result.error)
|
||||
_initializationStatus.value = result.error.lceError()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun isBuyAllowed(): Boolean = true
|
||||
|
||||
override fun isSellAllowed(): Boolean = false
|
||||
|
|
@ -42,18 +73,6 @@ internal class MercuryoService(private val environment: MercuryoEnvironment) : E
|
|||
|
||||
override fun availableForSell(currency: Currency): Boolean = false
|
||||
|
||||
override suspend fun update() {
|
||||
val result = performRequest { api.currencies(environment.apiVersion) }
|
||||
when {
|
||||
result is Result.Success && result.data.status == RESPONSE_SUCCESS_STATUS_CODE -> {
|
||||
handleSuccessfullyUpdatedData(data = result.data.data)
|
||||
}
|
||||
result is Result.Failure -> {
|
||||
availableMercuryoCurrencies.clear()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getUrl(
|
||||
action: CurrencyExchangeManager.Action,
|
||||
cryptoCurrency: CryptoCurrency,
|
||||
|
|
@ -89,6 +108,9 @@ internal class MercuryoService(private val environment: MercuryoEnvironment) : E
|
|||
private fun handleSuccessfullyUpdatedData(data: MercuryoCurrenciesResponse.Data) {
|
||||
availableMercuryoCurrencies.clear()
|
||||
availableMercuryoCurrencies.addAll(data.config.cryptoCurrencies)
|
||||
|
||||
Timber.i("Successfully updated")
|
||||
_initializationStatus.value = lceContent()
|
||||
}
|
||||
|
||||
private fun signature(address: String) = (address + environment.secret).calculateSha512().toHexString().lowercase()
|
||||
|
|
|
|||
|
|
@ -7,13 +7,20 @@ import com.tangem.common.services.Result
|
|||
import com.tangem.common.services.performRequest
|
||||
import com.tangem.datasource.api.common.createRetrofitInstance
|
||||
import com.tangem.domain.common.extensions.withIOContext
|
||||
import com.tangem.domain.core.utils.lceContent
|
||||
import com.tangem.domain.core.utils.lceError
|
||||
import com.tangem.domain.core.utils.lceLoading
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.tap.domain.model.Currency
|
||||
import com.tangem.tap.network.exchangeServices.CurrencyExchangeManager
|
||||
import com.tangem.tap.network.exchangeServices.ExchangeService
|
||||
import com.tangem.tap.network.exchangeServices.ExchangeServiceInitializationStatus
|
||||
import com.tangem.tap.network.exchangeServices.ExchangeUrlBuilder.Companion.SCHEME
|
||||
import com.tangem.tap.network.exchangeServices.moonpay.models.MoonPayAvailableCurrency
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import timber.log.Timber
|
||||
import javax.crypto.Mac
|
||||
import javax.crypto.spec.SecretKeySpec
|
||||
|
||||
|
|
@ -23,6 +30,12 @@ class MoonPayService(
|
|||
private val logEnabled: Boolean,
|
||||
) : ExchangeService {
|
||||
|
||||
override val initializationStatus: StateFlow<ExchangeServiceInitializationStatus>
|
||||
get() = _initializationStatus
|
||||
|
||||
private val _initializationStatus: MutableStateFlow<ExchangeServiceInitializationStatus> =
|
||||
MutableStateFlow(value = lceLoading())
|
||||
|
||||
private val api: MoonPayApi by lazy {
|
||||
createRetrofitInstance(
|
||||
baseUrl = MoonPayApi.MOOONPAY_BASE_URL,
|
||||
|
|
@ -34,14 +47,25 @@ class MoonPayService(
|
|||
|
||||
override suspend fun update() {
|
||||
withIOContext {
|
||||
Timber.i("Start updating")
|
||||
_initializationStatus.value = lceLoading()
|
||||
|
||||
performRequest {
|
||||
val userStatus = when (val result = performRequest { api.getUserStatus(apiKey) }) {
|
||||
is Result.Failure -> return@performRequest
|
||||
is Result.Failure -> {
|
||||
Timber.e("Failed to load user status", result.error)
|
||||
_initializationStatus.value = result.error.lceError()
|
||||
return@performRequest
|
||||
}
|
||||
is Result.Success -> result.data
|
||||
}
|
||||
|
||||
val currencies = when (val result = performRequest { api.getCurrencies(apiKey) }) {
|
||||
is Result.Failure -> return@performRequest
|
||||
is Result.Failure -> {
|
||||
Timber.e("Failed to load currencies", result.error)
|
||||
_initializationStatus.value = result.error.lceError()
|
||||
return@performRequest
|
||||
}
|
||||
is Result.Success -> result.data
|
||||
}
|
||||
|
||||
|
|
@ -58,6 +82,8 @@ class MoonPayService(
|
|||
)
|
||||
}
|
||||
|
||||
Timber.i("Successfully updated")
|
||||
_initializationStatus.value = lceContent()
|
||||
status = MoonPayStatus(currenciesToSell, userStatus, currencies)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ internal val Blockchain.moonPaySupportedCurrency: MoonPaySupportedCurrency?
|
|||
Filecoin -> MoonPaySupportedCurrency(networkCode = "filecoin", currencyCode = "fil")
|
||||
Sui -> MoonPaySupportedCurrency(networkCode = "sui", currencyCode = "sui")
|
||||
Core -> MoonPaySupportedCurrency(networkCode = "core", currencyCode = "core")
|
||||
Chiliz -> MoonPaySupportedCurrency(networkCode = "ethereum", currencyCode = "chz")
|
||||
ArbitrumTestnet -> null
|
||||
AvalancheTestnet -> null
|
||||
BinanceTestnet -> null
|
||||
|
|
@ -139,6 +140,7 @@ internal val Blockchain.moonPaySupportedCurrency: MoonPaySupportedCurrency?
|
|||
Casper -> null
|
||||
CasperTestnet -> null
|
||||
CoreTestnet -> null
|
||||
ChilizTestnet -> null
|
||||
Unknown -> null
|
||||
Xodex -> null
|
||||
Canxium -> null
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package com.tangem.tap.proxy
|
||||
|
||||
import com.tangem.domain.models.scan.CardDTO
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.redux.ReduxStateHolder
|
||||
import com.tangem.domain.redux.StateDialog
|
||||
|
|
@ -26,10 +25,8 @@ class AppStateHolder @Inject constructor() : ReduxStateHolder {
|
|||
var mainStore: Store<AppState>? = null
|
||||
var tangemSdkManager: TangemSdkManager? = null
|
||||
var exchangeService: ExchangeService? = null
|
||||
|
||||
fun getActualCard(): CardDTO? {
|
||||
return scanResponse?.card
|
||||
}
|
||||
var buyService: ExchangeService? = null
|
||||
var sellService: ExchangeService? = null
|
||||
|
||||
override fun dispatch(action: Action) {
|
||||
mainStore?.dispatch(action)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.tangem.tap.proxy.redux
|
|||
|
||||
import com.tangem.blockchainsdk.BlockchainSDKFactory
|
||||
import com.tangem.blockchainsdk.signer.TransactionSignerFactory
|
||||
import com.tangem.blockchainsdk.utils.ExcludedBlockchains
|
||||
import com.tangem.common.routing.AppRouter
|
||||
import com.tangem.core.navigation.share.ShareManager
|
||||
import com.tangem.core.navigation.url.UrlOpener
|
||||
|
|
@ -71,4 +72,5 @@ data class DaggerGraphState(
|
|||
val onrampFeatureToggles: OnrampFeatureToggles? = null,
|
||||
val environmentConfigStorage: EnvironmentConfigStorage? = null,
|
||||
val onboardingV2FeatureToggles: OnboardingV2FeatureToggles? = null,
|
||||
val excludedBlockchains: ExcludedBlockchains? = null,
|
||||
) : StateType
|
||||
|
|
@ -27,7 +27,7 @@ internal class DefaultRoutingComponent @AssistedInject constructor(
|
|||
|
||||
override val stack: Value<ChildStack<AppRoute, Child>> = childStack(
|
||||
source = navigationProvider.getOrCreateTyped(),
|
||||
serializer = AppRoute.serializer(),
|
||||
serializer = AppRoute.serializer(), // TODO Maybe set this to null for AppRoute.Onboarding case. Need to check
|
||||
initialConfiguration = getInitialRoute(),
|
||||
handleBackButton = false,
|
||||
childFactory = ::child,
|
||||
|
|
|
|||
|
|
@ -11,10 +11,8 @@ import com.tangem.features.disclaimer.api.components.DisclaimerComponent
|
|||
import com.tangem.features.managetokens.component.ManageTokensComponent
|
||||
import com.tangem.features.managetokens.component.ManageTokensSource
|
||||
import com.tangem.features.markets.details.MarketsTokenDetailsComponent
|
||||
import com.tangem.features.onramp.component.BuyCryptoComponent
|
||||
import com.tangem.features.onboarding.v2.entry.OnboardingEntryComponent
|
||||
import com.tangem.features.onramp.component.OnrampComponent
|
||||
import com.tangem.features.onramp.component.SellCryptoComponent
|
||||
import com.tangem.features.onramp.component.*
|
||||
import com.tangem.features.pushnotifications.api.navigation.PushNotificationsRouter
|
||||
import com.tangem.features.send.api.navigation.SendRouter
|
||||
import com.tangem.features.staking.api.navigation.StakingRouter
|
||||
|
|
@ -51,8 +49,10 @@ internal class ChildFactory @Inject constructor(
|
|||
private val manageTokensComponentFactory: ManageTokensComponent.Factory,
|
||||
private val marketsTokenDetailsComponentFactory: MarketsTokenDetailsComponent.Factory,
|
||||
private val onrampComponentFactory: OnrampComponent.Factory,
|
||||
private val onrampSuccessComponentFactory: OnrampSuccessComponent.Factory,
|
||||
private val buyCryptoComponentFactory: BuyCryptoComponent.Factory,
|
||||
private val sellCryptoComponentFactory: SellCryptoComponent.Factory,
|
||||
private val swapSelectTokensComponentFactory: SwapSelectTokensComponent.Factory,
|
||||
private val onboardingEntryComponentFactory: OnboardingEntryComponent.Factory,
|
||||
private val sendRouter: SendRouter,
|
||||
private val tokenDetailsRouter: TokenDetailsRouter,
|
||||
|
|
@ -197,10 +197,17 @@ internal class ChildFactory @Inject constructor(
|
|||
is AppRoute.Onramp -> {
|
||||
route.asComponentChild(
|
||||
contextProvider = contextProvider(route, contextFactory),
|
||||
params = OnrampComponent.Params(),
|
||||
params = OnrampComponent.Params(userWalletId = route.userWalletId, cryptoCurrency = route.currency),
|
||||
componentFactory = onrampComponentFactory,
|
||||
)
|
||||
}
|
||||
is AppRoute.OnrampSuccess -> {
|
||||
route.asComponentChild(
|
||||
contextProvider = contextProvider(route, contextFactory),
|
||||
params = OnrampSuccessComponent.Params(route.txId),
|
||||
componentFactory = onrampSuccessComponentFactory,
|
||||
)
|
||||
}
|
||||
is AppRoute.BuyCrypto -> {
|
||||
route.asComponentChild(
|
||||
contextProvider = contextProvider(route, contextFactory),
|
||||
|
|
@ -215,10 +222,20 @@ internal class ChildFactory @Inject constructor(
|
|||
componentFactory = sellCryptoComponentFactory,
|
||||
)
|
||||
}
|
||||
is AppRoute.SwapCrypto -> {
|
||||
route.asComponentChild(
|
||||
contextProvider = contextProvider(route, contextFactory),
|
||||
params = SwapSelectTokensComponent.Params(userWalletId = route.userWalletId),
|
||||
componentFactory = swapSelectTokensComponentFactory,
|
||||
)
|
||||
}
|
||||
is AppRoute.Onboarding -> {
|
||||
route.asComponentChild(
|
||||
contextProvider = contextProvider(route, contextFactory),
|
||||
params = OnboardingEntryComponent.Params(route.scanResponse),
|
||||
params = OnboardingEntryComponent.Params(
|
||||
scanResponse = route.scanResponse,
|
||||
startBackupFlow = route.startFromBackup,
|
||||
),
|
||||
componentFactory = onboardingEntryComponentFactory,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue