Updated on 2026-08-14

This commit is contained in:
Tangem 2024-04-05 17:27:54 +08:00
parent 500ea8e6f3
commit e2c8f84321
10 changed files with 99 additions and 90 deletions

View file

@ -12,9 +12,9 @@ import com.tangem.Log
import com.tangem.LogFormat
import com.tangem.TangemSdkLogger
import com.tangem.blockchain.common.AccountCreator
import com.tangem.blockchain.common.datastorage.BlockchainDataStorage
import com.tangem.blockchain.common.logging.BlockchainSDKLogger
import com.tangem.blockchain.network.BlockchainSdkRetrofitBuilder
import com.tangem.blockchainsdk.BlockchainSDKFactory
import com.tangem.core.analytics.Analytics
import com.tangem.core.analytics.filter.OneTimeEventFilter
import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
@ -156,9 +156,6 @@ internal class TapApplication : Application(), ImageLoaderFactory {
@Inject
lateinit var oneTimeEventFilter: OneTimeEventFilter
@Inject
lateinit var blockchainDataStorage: BlockchainDataStorage
@Inject
lateinit var accountCreator: AccountCreator
@ -188,6 +185,9 @@ internal class TapApplication : Application(), ImageLoaderFactory {
@Inject
lateinit var settingsRepository: SettingsRepository
@Inject
lateinit var blockchainSDKFactory: BlockchainSDKFactory
// endregion Injected
override fun onCreate() {
@ -223,6 +223,8 @@ internal class TapApplication : Application(), ImageLoaderFactory {
} else {
initUserWalletsListManager()
}
blockchainSDKFactory.init()
}
val configLoader = FeaturesLocalLoader(assetReader, MoshiConverter.sdkMoshi, BuildConfig.ENVIRONMENT)
@ -268,7 +270,6 @@ internal class TapApplication : Application(), ImageLoaderFactory {
balanceHidingRepository = balanceHidingRepository,
walletsRepository = walletsRepository,
sendFeatureToggles = sendFeatureToggles,
blockchainDataStorage = blockchainDataStorage,
accountCreator = accountCreator,
userWalletsListManagerFeatureToggles = userWalletsListManagerFeatureToggles,
generalUserWalletsListManager = generalUserWalletsListManager,
@ -279,6 +280,7 @@ internal class TapApplication : Application(), ImageLoaderFactory {
tangemSdkLogger = tangemSdkLogger,
blockchainSDKLogger = blockchainSDKLogger,
settingsRepository = settingsRepository,
blockchainSDKFactory = blockchainSDKFactory,
),
),
)

View file

@ -1,15 +1,11 @@
package com.tangem.tap.di.domain
import com.squareup.moshi.Moshi
import com.tangem.blockchain.common.AccountCreator
import com.tangem.blockchain.common.datastorage.BlockchainDataStorage
import com.tangem.blockchain.common.logging.BlockchainSDKLogger
import com.tangem.blockchainsdk.BlockchainSDKFactory
import com.tangem.datasource.asset.AssetReader
import com.tangem.datasource.config.ConfigManager
import com.tangem.datasource.di.SdkMoshi
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.datasource.local.walletmanager.WalletManagersStore
import com.tangem.domain.feedback.FeedbackManagerFeatureToggles
import com.tangem.domain.walletmanager.DefaultWalletManagersFacade
import com.tangem.domain.walletmanager.WalletManagersFacade
import com.tangem.feature.onboarding.data.MnemonicRepository
@ -28,26 +24,18 @@ internal object WalletManagersFacadeModule {
fun provideWalletManagersFacade(
walletManagersStore: WalletManagersStore,
userWalletsStore: UserWalletsStore,
configManager: ConfigManager,
blockchainDataStorage: BlockchainDataStorage,
accountCreator: AccountCreator,
mnemonicRepository: MnemonicRepository,
assetReader: AssetReader,
@SdkMoshi moshi: Moshi,
blockchainSDKLogger: BlockchainSDKLogger,
feedbackManagerFeatureToggles: FeedbackManagerFeatureToggles,
mnemonicRepository: MnemonicRepository,
blockchainSDKFactory: BlockchainSDKFactory,
): WalletManagersFacade {
return DefaultWalletManagersFacade(
walletManagersStore = walletManagersStore,
userWalletsStore = userWalletsStore,
configManager = configManager,
blockchainDataStorage = blockchainDataStorage,
assetReader = assetReader,
moshi = moshi,
mnemonic = mnemonicRepository.generateDefaultMnemonic(),
accountCreator = accountCreator,
blockchainSDKLogger = blockchainSDKLogger,
feedbackManagerFeatureToggles = feedbackManagerFeatureToggles,
blockchainSDKFactory = blockchainSDKFactory,
)
}
}

View file

@ -1,9 +1,7 @@
package com.tangem.tap.domain
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.core.analytics.Analytics
import com.tangem.core.analytics.models.Basic
import com.tangem.datasource.config.ConfigManager
@ -12,14 +10,12 @@ 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.common.extensions.inject
import com.tangem.tap.common.extensions.setContext
import com.tangem.tap.common.redux.global.GlobalAction
import com.tangem.tap.features.details.redux.walletconnect.WalletConnectAction
import com.tangem.tap.features.disclaimer.createDisclaimer
import com.tangem.tap.features.disclaimer.redux.DisclaimerAction
import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsAction
import com.tangem.tap.proxy.redux.DaggerGraphState
import com.tangem.tap.store
import com.tangem.tap.tangemSdkManager
import com.tangem.utils.coroutines.AppCoroutineDispatcherProvider
@ -32,29 +28,12 @@ class TapWalletManager(
private val dispatchers: CoroutineDispatcherProvider = AppCoroutineDispatcherProvider(),
) {
private val blockchainSdkConfig by lazy {
store.state.globalState.configManager?.config?.blockchainSdkConfig ?: BlockchainSdkConfig()
}
private var loadUserWalletDataJob: Job? = null
set(value) {
field?.cancel()
field = value
}
val walletManagerFactory: WalletManagerFactory by lazy {
WalletManagerFactory(
config = blockchainSdkConfig,
accountCreator = store.inject(DaggerGraphState::accountCreator),
blockchainDataStorage = store.inject(DaggerGraphState::blockchainDataStorage),
loggers = if (store.inject(DaggerGraphState::feedbackManagerFeatureToggles).isLocalLogsEnabled) {
listOf(store.inject(DaggerGraphState::blockchainSDKLogger))
} else {
emptyList()
},
)
}
suspend fun onWalletSelected(userWallet: UserWallet, sendAnalyticsEvent: Boolean) {
// If a previous job was running, it gets cancelled before the new one starts,
// ensuring that only one job is active at any given time.

View file

@ -6,11 +6,14 @@ import com.tangem.domain.common.extensions.withMainContext
import com.tangem.domain.demo.DemoConfig
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.tap.common.entities.ProgressState
import com.tangem.tap.common.extensions.inject
import com.tangem.tap.domain.model.Currency
import com.tangem.tap.features.onboarding.products.note.redux.OnboardingNoteAction
import com.tangem.tap.proxy.redux.DaggerGraphState
import com.tangem.tap.scope
import com.tangem.tap.store
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import org.rekotlin.Action
/**
@ -19,21 +22,23 @@ import org.rekotlin.Action
internal class DemoOnboardingNoteMiddleware : DemoMiddleware {
override fun tryHandle(config: DemoConfig, scanResponse: ScanResponse, action: Action): Boolean {
val globalState = store.state.globalState
val noteState = store.state.onboardingNoteState
when (action) {
return when (action) {
is OnboardingNoteAction.Balance.Update -> {
val walletManager = if (noteState.walletManager != null) {
noteState.walletManager
} else {
val wmFactory = globalState.tapWalletManager.walletManagerFactory
val walletManager = wmFactory.makePrimaryWalletManager(scanResponse).guard {
val wmFactory = runBlocking {
store.inject(DaggerGraphState::blockchainSDKFactory).getWalletManagerFactorySync()
}
val walletManager = wmFactory?.makePrimaryWalletManager(scanResponse).guard {
return false
}
store.dispatch(OnboardingNoteAction.SetWalletManager(walletManager))
walletManager
}
val balanceAmount = config.getBalance(walletManager.wallet.blockchain)
val loadedBalance = noteState.walletBalance.copy(
value = balanceAmount.value!!,
@ -42,6 +47,7 @@ internal class DemoOnboardingNoteMiddleware : DemoMiddleware {
error = null,
criticalError = null,
)
walletManager.wallet.setAmount(balanceAmount)
scope.launch {
@ -53,7 +59,7 @@ internal class DemoOnboardingNoteMiddleware : DemoMiddleware {
}
return true
}
else -> false
}
return false
}
}

View file

@ -23,12 +23,14 @@ import com.tangem.tap.features.home.RUSSIA_COUNTRY_CODE
import com.tangem.tap.features.onboarding.OnboardingDialog
import com.tangem.tap.features.onboarding.OnboardingHelper
import com.tangem.tap.mainScope
import com.tangem.tap.proxy.redux.DaggerGraphState
import com.tangem.tap.scope
import com.tangem.tap.store
import com.tangem.tap.tangemSdkManager
import com.tangem.utils.extensions.DELAY_SDK_DIALOG_CLOSE
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import org.rekotlin.Action
import org.rekotlin.DispatchFunction
import org.rekotlin.Middleware
@ -120,8 +122,10 @@ private fun handleNoteAction(appState: () -> AppState?, action: Action, dispatch
val walletManager = if (noteState.walletManager != null) {
noteState.walletManager
} else {
val wmFactory = globalState.tapWalletManager.walletManagerFactory
val walletManager = wmFactory.makePrimaryWalletManager(scanResponse).guard {
val wmFactory = runBlocking {
store.inject(DaggerGraphState::blockchainSDKFactory).getWalletManagerFactorySync()
}
val walletManager = wmFactory?.makePrimaryWalletManager(scanResponse).guard {
val message = "Loading cancelled. Cause: wallet manager didn't created"
val customError = TapError.CustomError(message)
store.dispatchErrorNotification(customError)

View file

@ -36,6 +36,7 @@ import com.tangem.tap.userWalletsListManager
import com.tangem.utils.extensions.DELAY_SDK_DIALOG_CLOSE
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import org.rekotlin.Action
import org.rekotlin.DispatchFunction
import org.rekotlin.Middleware
@ -244,8 +245,10 @@ private fun handle(action: Action, dispatch: DispatchFunction) {
val walletManager = if (twinCardsState.walletManager != null) {
twinCardsState.walletManager
} else {
val wmFactory = globalState.tapWalletManager.walletManagerFactory
val walletManager = wmFactory.makePrimaryWalletManager(getScanResponse()).guard {
val wmFactory = runBlocking {
store.inject(DaggerGraphState::blockchainSDKFactory).getWalletManagerFactorySync()
}
val walletManager = wmFactory?.makePrimaryWalletManager(getScanResponse()).guard {
val message = "Loading cancelled. Cause: wallet manager didn't created"
val customError = TapError.CustomError(message)
store.dispatchErrorNotification(customError)

View file

@ -2,8 +2,8 @@ package com.tangem.tap.proxy.redux
import com.tangem.TangemSdkLogger
import com.tangem.blockchain.common.AccountCreator
import com.tangem.blockchain.common.datastorage.BlockchainDataStorage
import com.tangem.blockchain.common.logging.BlockchainSDKLogger
import com.tangem.blockchainsdk.BlockchainSDKFactory
import com.tangem.datasource.connection.NetworkConnectionManager
import com.tangem.domain.appcurrency.repository.AppCurrencyRepository
import com.tangem.domain.apptheme.repository.AppThemeModeRepository
@ -62,7 +62,6 @@ data class DaggerGraphState(
val sendRouter: SendRouter? = null,
val qrScanningRouter: QrScanningRouter? = null,
val currenciesRepository: CurrenciesRepository? = null,
val blockchainDataStorage: BlockchainDataStorage? = null,
val accountCreator: AccountCreator? = null,
val userWalletsListManagerFeatureToggles: UserWalletsListManagerFeatureToggles? = null,
val generalUserWalletsListManager: UserWalletsListManager? = null,
@ -73,4 +72,5 @@ data class DaggerGraphState(
val tangemSdkLogger: TangemSdkLogger? = null,
val blockchainSDKLogger: BlockchainSDKLogger? = null,
val settingsRepository: SettingsRepository? = null,
val blockchainSDKFactory: BlockchainSDKFactory? = null,
) : StateType

View file

@ -10,23 +10,20 @@ import com.tangem.blockchain.common.*
import com.tangem.blockchain.common.address.Address
import com.tangem.blockchain.common.address.AddressType
import com.tangem.blockchain.common.address.EstimationFeeAddressFactory
import com.tangem.blockchain.common.datastorage.BlockchainDataStorage
import com.tangem.blockchain.common.logging.BlockchainSDKLogger
import com.tangem.blockchain.common.pagination.Page
import com.tangem.blockchain.common.transaction.Fee
import com.tangem.blockchain.common.transaction.TransactionFee
import com.tangem.blockchain.common.txhistory.TransactionHistoryRequest
import com.tangem.blockchain.extensions.Result
import com.tangem.blockchain.extensions.SimpleResult
import com.tangem.blockchainsdk.BlockchainSDKFactory
import com.tangem.crypto.bip39.Mnemonic
import com.tangem.crypto.hdWallet.DerivationPath
import com.tangem.datasource.asset.AssetReader
import com.tangem.datasource.config.ConfigManager
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.datasource.local.walletmanager.WalletManagersStore
import com.tangem.domain.common.util.hasDerivation
import com.tangem.domain.demo.DemoConfig
import com.tangem.domain.feedback.FeedbackManagerFeatureToggles
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.tokens.model.Network
import com.tangem.domain.tokens.model.warnings.CryptoCurrencyWarning
@ -52,23 +49,12 @@ class DefaultWalletManagersFacade(
mnemonic: Mnemonic,
assetReader: AssetReader,
moshi: Moshi,
configManager: ConfigManager,
blockchainDataStorage: BlockchainDataStorage,
accountCreator: AccountCreator,
blockchainSDKLogger: BlockchainSDKLogger,
feedbackManagerFeatureToggles: FeedbackManagerFeatureToggles,
blockchainSDKFactory: BlockchainSDKFactory,
) : WalletManagersFacade {
private val demoConfig by lazy { DemoConfig() }
private val resultFactory by lazy { UpdateWalletManagerResultFactory() }
private val walletManagerFactory by lazy {
WalletManagerFactory(
configManager = configManager,
accountCreator = accountCreator,
blockchainDataStorage = blockchainDataStorage,
blockchainSDKLogger = if (feedbackManagerFeatureToggles.isLocalLogsEnabled) blockchainSDKLogger else null,
)
}
private val walletManagerFactory by lazy { WalletManagerFactory(blockchainSDKFactory) }
private val sdkTokenConverter by lazy { SdkTokenConverter() }
private val txHistoryStateConverter by lazy { SdkTransactionHistoryStateConverter() }
private val txHistoryItemConverter by lazy { SdkTransactionHistoryItemConverter(assetReader, moshi) }

View file

@ -1,37 +1,21 @@
package com.tangem.domain.walletmanager.utils
import com.tangem.blockchain.common.AccountCreator
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.DerivationParams
import com.tangem.blockchain.common.WalletManager
import com.tangem.blockchain.common.datastorage.BlockchainDataStorage
import com.tangem.blockchain.common.logging.BlockchainSDKLogger
import com.tangem.blockchainsdk.BlockchainSDKFactory
import com.tangem.crypto.hdWallet.DerivationPath
import com.tangem.datasource.config.ConfigManager
import com.tangem.domain.common.DerivationStyleProvider
import com.tangem.domain.common.extensions.makeWalletManagerForApp
import com.tangem.domain.common.util.derivationStyleProvider
import com.tangem.domain.models.scan.ScanResponse
import timber.log.Timber
import com.tangem.blockchain.common.WalletManagerFactory as BlockchainWalletManagerFactory
internal class WalletManagerFactory(
configManager: ConfigManager,
accountCreator: AccountCreator,
blockchainDataStorage: BlockchainDataStorage,
blockchainSDKLogger: BlockchainSDKLogger? = null,
private val blockchainSDKFactory: BlockchainSDKFactory,
) {
private val sdkWalletManagerFactory by lazy {
BlockchainWalletManagerFactory(
config = configManager.config.blockchainSdkConfig,
accountCreator = accountCreator,
blockchainDataStorage = blockchainDataStorage,
loggers = listOfNotNull(blockchainSDKLogger),
)
}
fun createWalletManager(
suspend fun createWalletManager(
scanResponse: ScanResponse,
blockchain: Blockchain,
derivationPath: DerivationPath?,
@ -39,7 +23,7 @@ internal class WalletManagerFactory(
val derivationParams = getDerivationParams(derivationPath, scanResponse.derivationStyleProvider)
return try {
sdkWalletManagerFactory.makeWalletManagerForApp(
blockchainSDKFactory.getWalletManagerFactorySync()?.makeWalletManagerForApp(
scanResponse = scanResponse,
blockchain = blockchain,
derivationParams = derivationParams,

View file

@ -0,0 +1,57 @@
package com.tangem.blockchainsdk.di
import com.squareup.moshi.Moshi
import com.tangem.blockchain.common.AccountCreator
import com.tangem.blockchain.common.datastorage.BlockchainDataStorage
import com.tangem.blockchain.common.logging.BlockchainSDKLogger
import com.tangem.blockchainsdk.BlockchainSDKFactory
import com.tangem.blockchainsdk.DefaultBlockchainSDKFactory
import com.tangem.blockchainsdk.config.RuntimeConfigStorage
import com.tangem.blockchainsdk.loader.ConfigLoader
import com.tangem.blockchainsdk.loader.LocalConfigLoader
import com.tangem.datasource.asset.AssetReader
import com.tangem.datasource.di.SdkMoshi
import com.tangem.libs.blockchain_sdk.BuildConfig
import com.tangem.utils.coroutines.AppCoroutineDispatcherProvider
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 BlockchainSDKFactoryModule {
@Provides
@Singleton
fun provideBlockchainSDKFactory(
@SdkMoshi moshi: Moshi,
assetReader: AssetReader,
dispatchers: AppCoroutineDispatcherProvider,
accountCreator: AccountCreator,
blockchainDataStorage: BlockchainDataStorage,
blockchainSDKLogger: BlockchainSDKLogger,
): BlockchainSDKFactory {
return DefaultBlockchainSDKFactory(
configLoader = createConfigLoader(moshi, assetReader, dispatchers),
configStorage = RuntimeConfigStorage(),
accountCreator = accountCreator,
blockchainDataStorage = blockchainDataStorage,
blockchainSDKLogger = blockchainSDKLogger,
)
}
private fun createConfigLoader(
moshi: Moshi,
assetReader: AssetReader,
dispatchers: AppCoroutineDispatcherProvider,
): ConfigLoader {
return LocalConfigLoader(
buildEnvironment = BuildConfig.ENVIRONMENT,
moshi = moshi,
assetReader = assetReader,
dispatchers = dispatchers,
)
}
}