diff --git a/app/src/main/java/com/tangem/tap/ApplicationEntryPoint.kt b/app/src/main/java/com/tangem/tap/ApplicationEntryPoint.kt index be2d822333..4018a9497e 100644 --- a/app/src/main/java/com/tangem/tap/ApplicationEntryPoint.kt +++ b/app/src/main/java/com/tangem/tap/ApplicationEntryPoint.kt @@ -4,7 +4,7 @@ import com.tangem.TangemSdkLogger import com.tangem.blockchainsdk.BlockchainSDKFactory import com.tangem.core.analytics.filter.OneTimeEventFilter import com.tangem.core.featuretoggle.manager.FeatureTogglesManager -import com.tangem.datasource.asset.reader.AssetReader +import com.tangem.datasource.asset.loader.AssetLoader import com.tangem.datasource.config.ConfigManager import com.tangem.datasource.connection.NetworkConnectionManager import com.tangem.datasource.local.token.UserTokensStore @@ -47,7 +47,7 @@ interface ApplicationEntryPoint { fun getAppStateHolder(): AppStateHolder - fun getAssetReader(): AssetReader + fun getAssetLoader(): AssetLoader fun getFeatureTogglesManager(): FeatureTogglesManager diff --git a/app/src/main/java/com/tangem/tap/TangemApplication.kt b/app/src/main/java/com/tangem/tap/TangemApplication.kt index 792d4a3d22..61617d611c 100644 --- a/app/src/main/java/com/tangem/tap/TangemApplication.kt +++ b/app/src/main/java/com/tangem/tap/TangemApplication.kt @@ -18,7 +18,7 @@ import com.tangem.core.analytics.filter.OneTimeEventFilter import com.tangem.core.featuretoggle.manager.FeatureTogglesManager import com.tangem.datasource.api.common.MoshiConverter import com.tangem.datasource.api.common.createNetworkLoggingInterceptor -import com.tangem.datasource.asset.reader.AssetReader +import com.tangem.datasource.asset.loader.AssetLoader import com.tangem.datasource.config.ConfigManager import com.tangem.datasource.config.FeaturesLocalLoader import com.tangem.datasource.config.models.Config @@ -92,8 +92,8 @@ abstract class TangemApplication : Application(), ImageLoaderFactory { private val configManager: ConfigManager get() = entryPoint.getConfigManager() - private val assetReader: AssetReader - get() = entryPoint.getAssetReader() + private val assetLoader: AssetLoader + get() = entryPoint.getAssetLoader() private val featureTogglesManager: FeatureTogglesManager get() = entryPoint.getFeatureTogglesManager() @@ -217,10 +217,12 @@ abstract class TangemApplication : Application(), ImageLoaderFactory { // [REDACTED_JIRA] runBlocking { featureTogglesManager.init() + initConfigManager( + loader = FeaturesLocalLoader(assetLoader, BuildConfig.ENVIRONMENT), + onComplete = ::initWithConfigDependency, + ) } - val configLoader = FeaturesLocalLoader(assetReader, MoshiConverter.sdkMoshi, BuildConfig.ENVIRONMENT) - initConfigManager(configLoader, ::initWithConfigDependency) initWarningMessagesManager() loadNativeLibraries() @@ -290,7 +292,7 @@ abstract class TangemApplication : Application(), ImageLoaderFactory { System.loadLibrary("TrustWalletCore") } - private fun initConfigManager(loader: FeaturesLocalLoader, onComplete: (Config) -> Unit) { + private suspend fun initConfigManager(loader: FeaturesLocalLoader, onComplete: (Config) -> Unit) { configManager.load(loader) { config -> store.dispatch(GlobalAction.SetConfigManager(configManager)) onComplete(config) diff --git a/app/src/main/java/com/tangem/tap/di/domain/WalletManagersFacadeModule.kt b/app/src/main/java/com/tangem/tap/di/domain/WalletManagersFacadeModule.kt index 2bd8c1d4c1..ac937e5a47 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/WalletManagersFacadeModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/WalletManagersFacadeModule.kt @@ -1,9 +1,7 @@ package com.tangem.tap.di.domain -import com.squareup.moshi.Moshi import com.tangem.blockchainsdk.BlockchainSDKFactory -import com.tangem.datasource.asset.reader.AssetReader -import com.tangem.datasource.di.SdkMoshi +import com.tangem.datasource.asset.loader.AssetLoader import com.tangem.datasource.local.userwallet.UserWalletsStore import com.tangem.datasource.local.walletmanager.WalletManagersStore import com.tangem.domain.walletmanager.DefaultWalletManagersFacade @@ -23,15 +21,13 @@ internal object WalletManagersFacadeModule { fun provideWalletManagersFacade( walletManagersStore: WalletManagersStore, userWalletsStore: UserWalletsStore, - assetReader: AssetReader, - @SdkMoshi moshi: Moshi, + assetLoader: AssetLoader, blockchainSDKFactory: BlockchainSDKFactory, ): WalletManagersFacade { return DefaultWalletManagersFacade( walletManagersStore = walletManagersStore, userWalletsStore = userWalletsStore, - assetReader = assetReader, - moshi = moshi, + assetLoader = assetLoader, blockchainSDKFactory = blockchainSDKFactory, ) } diff --git a/app/src/main/java/com/tangem/tap/domain/twins/TwinCardsManager.kt b/app/src/main/java/com/tangem/tap/domain/twins/TwinCardsManager.kt index 34b7dada02..7f242bb845 100644 --- a/app/src/main/java/com/tangem/tap/domain/twins/TwinCardsManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/twins/TwinCardsManager.kt @@ -1,40 +1,36 @@ package com.tangem.tap.domain.twins -import com.squareup.moshi.JsonAdapter -import com.squareup.moshi.Types import com.tangem.Message import com.tangem.blockchain.extensions.Result import com.tangem.common.CompletionResult import com.tangem.common.KeyPair import com.tangem.common.extensions.hexToBytes import com.tangem.common.extensions.toHexString -import com.tangem.datasource.api.common.MoshiConverter -import com.tangem.datasource.asset.reader.AssetReader import com.tangem.domain.models.scan.CardDTO import com.tangem.domain.models.scan.ScanResponse import com.tangem.operations.wallet.CreateWalletResponse +import com.tangem.tap.common.extensions.inject +import com.tangem.tap.proxy.redux.DaggerGraphState +import com.tangem.tap.store import com.tangem.tap.tangemSdkManager +import kotlinx.coroutines.flow.MutableStateFlow -class TwinCardsManager( - card: CardDTO, - assetReader: AssetReader, -) { +class TwinCardsManager(card: CardDTO) { private val firstCardId: String = card.cardId + private val publicKey: String = card.issuer.publicKey.toHexString() private var currentCardPublicKey: String? = null private var secondCardPublicKey: String? = null - private val issuerKeyPair: KeyPair = getIssuerKeys(assetReader, card.issuer.publicKey.toHexString()) + private val issuerKeyPairFlow = MutableStateFlow(value = null) suspend fun createFirstWallet(message: Message): CompletionResult { - val response = tangemSdkManager.createFirstTwinWallet( - cardId = firstCardId, - initialMessage = message, - ) - when (response) { - is CompletionResult.Success -> currentCardPublicKey = response.data.wallet.publicKey.toHexString() - is CompletionResult.Failure -> {} + val response = tangemSdkManager.createFirstTwinWallet(cardId = firstCardId, initialMessage = message) + + if (response is CompletionResult.Success) { + currentCardPublicKey = response.data.wallet.publicKey.toHexString() } + return response } @@ -46,58 +42,51 @@ class TwinCardsManager( val response = tangemSdkManager.createSecondTwinWallet( firstPublicKey = currentCardPublicKey!!, firstCardId = firstCardId, - issuerKeys = issuerKeyPair, + issuerKeys = getIssuerKeys(), preparingMessage = preparingMessage, creatingWalletMessage = creatingWalletMessage, initialMessage = initialMessage, ) - when (response) { - is CompletionResult.Success -> { - secondCardPublicKey = response.data.wallet.publicKey.toHexString() - } - is CompletionResult.Failure -> {} + if (response is CompletionResult.Success) { + secondCardPublicKey = response.data.wallet.publicKey.toHexString() } + return response } suspend fun complete(message: Message): Result { val response = tangemSdkManager.finalizeTwin( secondCardPublicKey = secondCardPublicKey!!.hexToBytes(), - issuerKeyPair = issuerKeyPair, + issuerKeyPair = getIssuerKeys(), cardId = firstCardId, initialMessage = message, ) + return when (response) { is CompletionResult.Success -> Result.Success(response.data) is CompletionResult.Failure -> Result.fromTangemSdkError(response.error) } } - companion object { - private fun getIssuerKeys(reader: AssetReader, publicKey: String): KeyPair { - val issuer = getIssuers(reader).first { it.publicKey == publicKey } - return KeyPair( - publicKey = issuer.publicKey.hexToBytes(), - privateKey = issuer.privateKey.hexToBytes(), - ) - } + private suspend fun getIssuerKeys(): KeyPair { + issuerKeyPairFlow.value?.let { return it } - private fun getAdapter(): JsonAdapter> { - return MoshiConverter.sdkMoshi.adapter( - Types.newParameterizedType(List::class.java, Issuer::class.java), - ) - } + val assetLoader = store.inject(DaggerGraphState::assetLoader) + val issuer = assetLoader.loadList(fileName = ISSUERS_FILE_NAME) + .first { it.publicKey == publicKey } - @Deprecated(message = "Use AssetReader instead") - private fun getIssuers(reader: AssetReader): List { - val file = reader.readJson(fileName = "tangem-app-config/issuers") - return getAdapter().fromJson(file)!! + return KeyPair( + publicKey = issuer.publicKey.hexToBytes(), + privateKey = issuer.privateKey.hexToBytes(), + ).also { + issuerKeyPairFlow.value = it } } + + private companion object { + const val ISSUERS_FILE_NAME = "tangem-app-config/issuers" + } } -private class Issuer( - val privateKey: String, - val publicKey: String, -) \ No newline at end of file +private class Issuer(val privateKey: String, val publicKey: String) \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsAction.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsAction.kt index 5a12a5ea5e..ca00a0c255 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsAction.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsAction.kt @@ -3,7 +3,6 @@ package com.tangem.tap.features.onboarding.products.twins.redux import com.tangem.Message import com.tangem.blockchain.common.WalletManager import com.tangem.common.extensions.VoidCallback -import com.tangem.datasource.asset.reader.AssetReader import com.tangem.domain.models.scan.ScanResponse import com.tangem.tap.domain.TapError import com.tangem.tap.domain.twins.TwinCardsManager @@ -27,7 +26,7 @@ sealed class TwinCardsAction : Action { } sealed class Wallet : TwinCardsAction() { - data class LaunchFirstStep(val initialMessage: Message, val reader: AssetReader) : TwinCardsAction() + data class LaunchFirstStep(val initialMessage: Message) : TwinCardsAction() data class LaunchSecondStep( val initialMessage: Message, val preparingMessage: Message, diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsMiddleware.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsMiddleware.kt index b59d2efa0b..033b790e84 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsMiddleware.kt @@ -165,10 +165,7 @@ private fun handle(action: Action, dispatch: DispatchFunction) { } } is TwinCardsAction.Wallet.LaunchFirstStep -> { - val manager = TwinCardsManager( - card = getScanResponse().card, - assetReader = action.reader, - ) + val manager = TwinCardsManager(card = getScanResponse().card) store.dispatch(TwinCardsAction.CardsManager.Set(manager)) scope.launch { diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/ui/OnboardingTwinsFragment.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/ui/OnboardingTwinsFragment.kt index b4260dd2e8..2cbf5949d1 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/ui/OnboardingTwinsFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/ui/OnboardingTwinsFragment.kt @@ -15,7 +15,6 @@ import com.tangem.common.extensions.VoidCallback import com.tangem.core.analytics.Analytics import com.tangem.core.navigation.ShareElement import com.tangem.core.ui.extensions.setStatusBarColor -import com.tangem.datasource.asset.reader.AssetReader import com.tangem.domain.common.TwinCardNumber import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.wallets.models.Artwork @@ -35,15 +34,11 @@ import com.tangem.tap.store import com.tangem.wallet.R import com.tangem.wallet.databinding.LayoutOnboardingContainerTopBinding import dagger.hilt.android.AndroidEntryPoint -import javax.inject.Inject @Suppress("LargeClass") @AndroidEntryPoint internal class OnboardingTwinsFragment : BaseOnboardingFragment() { - @Inject - lateinit var assetReader: AssetReader - private val mainBinding by lazy { binding.vMain } private var previousStep: TwinCardsStep = TwinCardsStep.None @@ -260,7 +255,6 @@ internal class OnboardingTwinsFragment : BaseOnboardingFragment( store.dispatch( TwinCardsAction.Wallet.LaunchFirstStep( initialMessage = Message(getString(R.string.twins_recreate_title_format, twinIndexNumber)), - reader = assetReader, ), ) } diff --git a/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphState.kt b/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphState.kt index b89bfaeb6f..2905024817 100644 --- a/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphState.kt +++ b/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphState.kt @@ -4,6 +4,7 @@ import com.tangem.TangemSdkLogger import com.tangem.blockchainsdk.BlockchainSDKFactory import com.tangem.core.decompose.context.AppComponentContext import com.tangem.core.navigation.email.EmailSender +import com.tangem.datasource.asset.loader.AssetLoader import com.tangem.datasource.connection.NetworkConnectionManager import com.tangem.domain.appcurrency.repository.AppCurrencyRepository import com.tangem.domain.apptheme.repository.AppThemeModeRepository @@ -77,6 +78,7 @@ data class DaggerGraphState( val blockchainSDKFactory: BlockchainSDKFactory? = null, val emailSender: EmailSender? = null, val saveBlockchainErrorUseCase: SaveBlockchainErrorUseCase? = null, + val assetLoader: AssetLoader? = null, val detailsFeatureToggles: DetailsFeatureToggles? = null, val detailsEntryPoint: DetailsEntryPoint? = null, ) : StateType \ No newline at end of file diff --git a/core/datasource/build.gradle.kts b/core/datasource/build.gradle.kts index 26d30378a2..4deb2329d1 100644 --- a/core/datasource/build.gradle.kts +++ b/core/datasource/build.gradle.kts @@ -69,4 +69,9 @@ dependencies { implementation(deps.room.runtime) implementation(deps.room.ktx) kapt(deps.room.compiler) + + testImplementation(deps.test.coroutine) + testImplementation(deps.test.junit) + testImplementation(deps.test.mockk) + testImplementation(deps.test.truth) } \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/asset/loader/AssetLoader.kt b/core/datasource/src/main/java/com/tangem/datasource/asset/loader/AssetLoader.kt index 042319e1f4..6c04362a3c 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/asset/loader/AssetLoader.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/asset/loader/AssetLoader.kt @@ -5,27 +5,31 @@ import com.squareup.moshi.Types import com.squareup.moshi.adapter import com.tangem.datasource.asset.reader.AssetReader import com.tangem.datasource.di.NetworkMoshi -import com.tangem.utils.coroutines.CoroutineDispatcherProvider -import com.tangem.utils.coroutines.runCatching import timber.log.Timber import javax.inject.Inject +import javax.inject.Singleton /** * Asset file loader * + * @property assetReader asset reader + * @property moshi moshi + * + * @see Documentation + * [REDACTED_AUTHOR] */ +@Singleton class AssetLoader @Inject constructor( val assetReader: AssetReader, @NetworkMoshi val moshi: Moshi, - val dispatchers: CoroutineDispatcherProvider, ) { /** Load content [Content] of asset file [fileName] */ @OptIn(ExperimentalStdlibApi::class) suspend inline fun load(fileName: String): Content? { - return runCatching(dispatchers.io) { - val json = assetReader.readJson(fileName = fileName) + return runCatching { + val json = assetReader.read(fullFileName = "$fileName.json") moshi.adapter().fromJson(json) } @@ -43,8 +47,8 @@ class AssetLoader @Inject constructor( /** Load list [V] values of asset file [fileName] */ suspend inline fun loadList(fileName: String): List { - return runCatching(dispatchers.io) { - val json = assetReader.readJson(fileName = fileName) + return runCatching { + val json = assetReader.read(fullFileName = "$fileName.json") val type = Types.newParameterizedType(List::class.java, V::class.java) val adapter = moshi.adapter>(type) @@ -65,8 +69,8 @@ class AssetLoader @Inject constructor( /** Load map [String] keys and [V] values of asset file [fileName] */ suspend inline fun loadMap(fileName: String): Map { - return runCatching(dispatchers.io) { - val json = assetReader.readJson(fileName = fileName) + return runCatching { + val json = assetReader.read(fullFileName = "$fileName.json") val type = Types.newParameterizedType(Map::class.java, String::class.java, V::class.java) val adapter = moshi.adapter>(type) diff --git a/core/datasource/src/main/java/com/tangem/datasource/asset/reader/AndroidAssetReader.kt b/core/datasource/src/main/java/com/tangem/datasource/asset/reader/AndroidAssetReader.kt index 4a8678e96d..139e082aa9 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/asset/reader/AndroidAssetReader.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/asset/reader/AndroidAssetReader.kt @@ -1,27 +1,23 @@ package com.tangem.datasource.asset.reader -import android.content.Context -import dagger.hilt.android.qualifiers.ApplicationContext +import android.content.res.AssetManager +import com.tangem.utils.coroutines.CoroutineDispatcherProvider +import kotlinx.coroutines.withContext import java.io.BufferedReader -import java.io.InputStream -import javax.inject.Inject /** * Implementation of asset file reader * - * @property context application context + * @property assetManager asset manager + * @property dispatchers dispatchers */ -internal class AndroidAssetReader @Inject constructor( - @ApplicationContext private val context: Context, +internal class AndroidAssetReader( + private val assetManager: AssetManager, + private val dispatchers: CoroutineDispatcherProvider, ) : AssetReader { - override fun readJson(fileName: String): String { - return openFile("$fileName.json") - .bufferedReader() + override suspend fun read(fullFileName: String): String = withContext(dispatchers.io) { + assetManager.open(fullFileName).bufferedReader() .use(BufferedReader::readText) } - - override fun openFile(file: String): InputStream { - return context.assets.open(file) - } } \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/asset/reader/AssetReader.kt b/core/datasource/src/main/java/com/tangem/datasource/asset/reader/AssetReader.kt index 46c3edea4a..a8c2053a87 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/asset/reader/AssetReader.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/asset/reader/AssetReader.kt @@ -1,17 +1,18 @@ package com.tangem.datasource.asset.reader -import java.io.InputStream - /** * Asset file reader * + * @see Documentation + * [REDACTED_AUTHOR] */ interface AssetReader { - /** Read content of json file [fileName] from asset */ - fun readJson(fileName: String): String - - /** Open a file [file] from asset as InputStream */ - fun openFile(file: String): InputStream + /** + * Read content of file from assets + * + * @param fullFileName name of file with extension. Example: file.json + */ + suspend fun read(fullFileName: String): String } \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/config/ConfigManager.kt b/core/datasource/src/main/java/com/tangem/datasource/config/ConfigManager.kt index 5cfaed8562..9c8a0d8127 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/config/ConfigManager.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/config/ConfigManager.kt @@ -10,7 +10,7 @@ interface ConfigManager { val config: Config - fun load(configLoader: Loader, onComplete: ((config: Config) -> Unit)? = null) + suspend fun load(configLoader: Loader, onComplete: ((config: Config) -> Unit)? = null) fun turnOff(name: String) diff --git a/core/datasource/src/main/java/com/tangem/datasource/config/ConfigManagerImpl.kt b/core/datasource/src/main/java/com/tangem/datasource/config/ConfigManagerImpl.kt index fe5ad1ad8e..094cc6c04b 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/config/ConfigManagerImpl.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/config/ConfigManagerImpl.kt @@ -19,7 +19,7 @@ internal class ConfigManagerImpl @Inject constructor() : ConfigManager { private var defaultConfig = Config() - override fun load(configLoader: Loader, onComplete: ((config: Config) -> Unit)?) { + override suspend fun load(configLoader: Loader, onComplete: ((config: Config) -> Unit)?) { configLoader.load { configModel -> setupFeature(configModel.features) setupConfigValues(configModel.configValues) diff --git a/core/datasource/src/main/java/com/tangem/datasource/config/FeaturesLocalLoader.kt b/core/datasource/src/main/java/com/tangem/datasource/config/FeaturesLocalLoader.kt index 5c162f28a8..205537191a 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/config/FeaturesLocalLoader.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/config/FeaturesLocalLoader.kt @@ -1,39 +1,25 @@ package com.tangem.datasource.config -import com.squareup.moshi.JsonAdapter -import com.squareup.moshi.Moshi -import com.tangem.datasource.asset.reader.AssetReader +import com.tangem.datasource.asset.loader.AssetLoader import com.tangem.datasource.config.models.ConfigModel import com.tangem.datasource.config.models.ConfigValueModel import com.tangem.datasource.config.models.FeatureModel -import timber.log.Timber /** [REDACTED_AUTHOR] */ -@Deprecated(message = "Use AssetReader instead") class FeaturesLocalLoader( - private val assetReader: AssetReader, - private val moshi: Moshi, + private val assetLoader: AssetLoader, buildEnvironment: String, ) : Loader { private val featuresName = "features_$buildEnvironment" private val configValuesName = "tangem-app-config/config_$buildEnvironment" - override fun load(onComplete: (ConfigModel) -> Unit) { - val config = try { - val featureAdapter: JsonAdapter = moshi.adapter(FeatureModel::class.java) - val valuesAdapter: JsonAdapter = moshi.adapter(ConfigValueModel::class.java) - - val jsonFeatures = assetReader.readJson(featuresName) - val jsonConfigValues = assetReader.readJson(configValuesName) - - ConfigModel(featureAdapter.fromJson(jsonFeatures), valuesAdapter.fromJson(jsonConfigValues)) - } catch (ex: Exception) { - Timber.e(ex) - ConfigModel.empty() - } - onComplete(config) + override suspend fun load(onComplete: (ConfigModel) -> Unit) { + ConfigModel( + features = assetLoader.load(fileName = featuresName), + configValues = assetLoader.load(fileName = configValuesName), + ).also(onComplete) } } \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/config/Loader.kt b/core/datasource/src/main/java/com/tangem/datasource/config/Loader.kt index 515e2b0d23..c5f9b0073e 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/config/Loader.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/config/Loader.kt @@ -4,5 +4,5 @@ package com.tangem.datasource.config [REDACTED_AUTHOR] */ interface Loader { - fun load(onComplete: (T) -> Unit) + suspend fun load(onComplete: (T) -> Unit) } \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/di/AssetModule.kt b/core/datasource/src/main/java/com/tangem/datasource/di/AssetModule.kt deleted file mode 100644 index b39cb4f1a3..0000000000 --- a/core/datasource/src/main/java/com/tangem/datasource/di/AssetModule.kt +++ /dev/null @@ -1,18 +0,0 @@ -package com.tangem.datasource.di - -import com.tangem.datasource.asset.reader.AndroidAssetReader -import com.tangem.datasource.asset.reader.AssetReader -import dagger.Binds -import dagger.Module -import dagger.hilt.InstallIn -import dagger.hilt.components.SingletonComponent -import javax.inject.Singleton - -@Module -@InstallIn(SingletonComponent::class) -internal interface AssetModule { - - @Binds - @Singleton - fun bindAsserReader(androidAssetReader: AndroidAssetReader): AssetReader -} \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/di/AssetReaderModule.kt b/core/datasource/src/main/java/com/tangem/datasource/di/AssetReaderModule.kt new file mode 100644 index 0000000000..196ec8d836 --- /dev/null +++ b/core/datasource/src/main/java/com/tangem/datasource/di/AssetReaderModule.kt @@ -0,0 +1,26 @@ +package com.tangem.datasource.di + +import android.content.Context +import com.tangem.datasource.asset.reader.AndroidAssetReader +import com.tangem.datasource.asset.reader.AssetReader +import com.tangem.utils.coroutines.CoroutineDispatcherProvider +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.android.qualifiers.ApplicationContext +import dagger.hilt.components.SingletonComponent +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +internal object AssetReaderModule { + + @Singleton + @Provides + fun providesAsserReader( + @ApplicationContext context: Context, + dispatchers: CoroutineDispatcherProvider, + ): AssetReader { + return AndroidAssetReader(context.assets, dispatchers) + } +} \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/di/TestnetTokensStorageModule.kt b/core/datasource/src/main/java/com/tangem/datasource/di/TestnetTokensStorageModule.kt index bbd6ac04ad..e23f80cbb6 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/di/TestnetTokensStorageModule.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/di/TestnetTokensStorageModule.kt @@ -1,8 +1,6 @@ package com.tangem.datasource.di -import com.squareup.moshi.Moshi -import com.squareup.moshi.adapter -import com.tangem.datasource.asset.reader.AssetReader +import com.tangem.datasource.asset.loader.AssetLoader import com.tangem.datasource.local.testnet.DefaultTestnetTokensStorage import com.tangem.datasource.local.testnet.TestnetTokensStorage import dagger.Module @@ -16,12 +14,11 @@ import javax.inject.Singleton */ @Module @InstallIn(SingletonComponent::class) -object TestnetTokensStorageModule { +internal object TestnetTokensStorageModule { - @OptIn(ExperimentalStdlibApi::class) @Provides @Singleton - fun providesTestnetTokensStorage(assetReader: AssetReader, @SdkMoshi moshi: Moshi): TestnetTokensStorage { - return DefaultTestnetTokensStorage(assetReader = assetReader, adapter = moshi.adapter()) + fun providesTestnetTokensStorage(assetLoader: AssetLoader): TestnetTokensStorage { + return DefaultTestnetTokensStorage(assetLoader) } } \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/testnet/DefaultTestnetTokensStorage.kt b/core/datasource/src/main/java/com/tangem/datasource/local/testnet/DefaultTestnetTokensStorage.kt index 878702cd4f..b88bdda0bc 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/local/testnet/DefaultTestnetTokensStorage.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/local/testnet/DefaultTestnetTokensStorage.kt @@ -1,29 +1,21 @@ package com.tangem.datasource.local.testnet -import com.squareup.moshi.JsonAdapter -import com.tangem.datasource.asset.reader.AssetReader +import com.tangem.datasource.asset.loader.AssetLoader import com.tangem.datasource.local.testnet.models.TestnetTokensConfig /** * Default implementation for storing testnet tokens data * - * @property assetReader file reader from assets - * @property adapter adapter for parsing testnet tokens config + * @property assetLoader asset loader * [REDACTED_AUTHOR] */ internal class DefaultTestnetTokensStorage( - private val assetReader: AssetReader, - private val adapter: JsonAdapter, + private val assetLoader: AssetLoader, ) : TestnetTokensStorage { - @Deprecated(message = "Use AssetReader instead") - override fun getConfig(): TestnetTokensConfig { - return requireNotNull( - value = adapter.fromJson( - assetReader.readJson(fileName = LOCAL_CONFIG_PATH), - ), - ) + override suspend fun getConfig(): TestnetTokensConfig { + return requireNotNull(assetLoader.load(fileName = LOCAL_CONFIG_PATH)) } private companion object { diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/testnet/TestnetTokensStorage.kt b/core/datasource/src/main/java/com/tangem/datasource/local/testnet/TestnetTokensStorage.kt index 7f091e98e6..7cbd7a6602 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/local/testnet/TestnetTokensStorage.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/local/testnet/TestnetTokensStorage.kt @@ -10,5 +10,5 @@ import com.tangem.datasource.local.testnet.models.TestnetTokensConfig interface TestnetTokensStorage { /** Get a testnet tokens data */ - fun getConfig(): TestnetTokensConfig + suspend fun getConfig(): TestnetTokensConfig } \ No newline at end of file diff --git a/core/datasource/src/test/kotlin/com/tangem/datasource/asset/loader/AssetLoaderTest.kt b/core/datasource/src/test/kotlin/com/tangem/datasource/asset/loader/AssetLoaderTest.kt new file mode 100644 index 0000000000..529f1271a9 --- /dev/null +++ b/core/datasource/src/test/kotlin/com/tangem/datasource/asset/loader/AssetLoaderTest.kt @@ -0,0 +1,119 @@ +package com.tangem.datasource.asset.loader + +import com.google.common.truth.Truth +import com.squareup.moshi.JsonAdapter +import com.squareup.moshi.Moshi +import com.squareup.moshi.Types +import com.squareup.moshi.adapter +import com.tangem.datasource.api.express.models.response.Asset +import com.tangem.datasource.asset.reader.AssetReader +import io.mockk.coEvery +import io.mockk.coVerifyOrder +import io.mockk.every +import io.mockk.mockk +import kotlinx.coroutines.test.runTest +import org.junit.Test + +/** +[REDACTED_AUTHOR] + */ +@OptIn(ExperimentalStdlibApi::class) +class AssetLoaderTest { + + private val assetReader = mockk() + private val moshi = mockk() + private val assetLoader = AssetLoader(assetReader = assetReader, moshi = moshi) + + @Test + fun load() = runTest { + everyReadingJson() returns assetObjectJson + + val jsonAdapter = mockk>() + every { moshi.adapter() } returns jsonAdapter + every { jsonAdapter.fromJson(assetObjectJson) } returns assetObject + + val actual = assetLoader.load(fileName = JSON_FILE_NAME) + + coVerifyOrder { + assetReader.read("$JSON_FILE_NAME.json") + jsonAdapter.fromJson(assetObjectJson) + } + + Truth.assertThat(actual).isEqualTo(assetObject) + } + + @Test + fun loadList() = runTest { + everyReadingJson() returns assetListJson + + val jsonAdapter = mockk>>() + val types = Types.newParameterizedType(List::class.java, Asset::class.java) + every { moshi.adapter>(types) } returns jsonAdapter + every { jsonAdapter.fromJson(assetListJson) } returns assetList + + val actual = assetLoader.loadList(fileName = JSON_FILE_NAME) + + coVerifyOrder { + assetReader.read("$JSON_FILE_NAME.json") + jsonAdapter.fromJson(assetListJson) + } + + Truth.assertThat(actual).isEqualTo(assetList) + } + + @Test + fun loadMap() = runTest { + everyReadingJson() returns assetMapJson + + val jsonAdapter = mockk>>() + val types = Types.newParameterizedType(Map::class.java, String::class.java, Asset::class.java) + every { moshi.adapter>(types) } returns jsonAdapter + every { jsonAdapter.fromJson(assetMapJson) } returns assetMap + + val actual = assetLoader.loadMap(fileName = JSON_FILE_NAME) + + coVerifyOrder { + assetReader.read("$JSON_FILE_NAME.json") + jsonAdapter.fromJson(assetMapJson) + } + + Truth.assertThat(actual).isEqualTo(assetMap) + } + + private fun everyReadingJson() = coEvery { assetReader.read("$JSON_FILE_NAME.json") } + + private companion object { + + const val JSON_FILE_NAME = "config" + + val assetObject = Asset( + contractAddress = "0x0000000000000000000000000000000000000000", + network = "Network", + exchangeAvailable = true, + ) + + val assetList = listOf(assetObject, assetObject) + + val assetMap = mapOf("key1" to assetObject, "key2" to assetObject) + + val assetObjectJson = """ + { + "contractAddress": "${assetObject.contractAddress}", + "network": "${assetObject.network}", + "exchangeAvailable": ${assetObject.exchangeAvailable} + } + """.trimIndent() + + val assetListJson = """ + $assetObjectJson, + $assetObjectJson + """.trimIndent() + + val assetMapJson = """ + { + "key1": $assetObjectJson, + "key2": $assetObjectJson + } + """.trimIndent() + } +} \ No newline at end of file diff --git a/core/datasource/src/test/kotlin/com/tangem/datasource/asset/reader/AndroidAssetReaderTest.kt b/core/datasource/src/test/kotlin/com/tangem/datasource/asset/reader/AndroidAssetReaderTest.kt new file mode 100644 index 0000000000..c1beef670e --- /dev/null +++ b/core/datasource/src/test/kotlin/com/tangem/datasource/asset/reader/AndroidAssetReaderTest.kt @@ -0,0 +1,51 @@ +package com.tangem.datasource.asset.reader + +import android.content.res.AssetManager +import com.google.common.truth.Truth +import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider +import io.mockk.every +import io.mockk.mockk +import kotlinx.coroutines.test.runTest +import org.junit.Test +import java.io.IOException + +/** +[REDACTED_AUTHOR] + */ +internal class AndroidAssetReaderTest { + + private val assetManager = mockk() + private val assetReader = AndroidAssetReader(assetManager, TestingCoroutineDispatcherProvider()) + + @Test + fun read_content() = runTest { + every { assetManager.open(FILE_NAME) } returns json.byteInputStream() + + val actual = assetReader.read(fullFileName = FILE_NAME) + + Truth.assertThat(actual).isEqualTo(json) + } + + @Test + fun read_error() = runTest { + val exception = IOException("Error") + every { assetManager.open(FILE_NAME) } throws exception + + runCatching { assetReader.read(fullFileName = FILE_NAME) } + .onSuccess { throw IllegalStateException("Error should be thrown") } + .onFailure { + Truth.assertThat(it).isEqualTo(exception) + } + } + + private companion object { + + const val FILE_NAME = "file.json" + + val json = """ + { + "key": "value" + } + """.trimIndent() + } +} \ No newline at end of file diff --git a/core/featuretoggles/build.gradle.kts b/core/featuretoggles/build.gradle.kts index d775494d39..410ef17d0e 100644 --- a/core/featuretoggles/build.gradle.kts +++ b/core/featuretoggles/build.gradle.kts @@ -26,6 +26,7 @@ dependencies { /** Core modules */ implementation(projects.core.datasource) + implementation(projects.core.utils) testImplementation(deps.test.coroutine) testImplementation(deps.test.junit) diff --git a/core/featuretoggles/src/main/kotlin/com/tangem/core/featuretoggle/di/FeatureTogglesManagerModule.kt b/core/featuretoggles/src/main/kotlin/com/tangem/core/featuretoggle/di/FeatureTogglesManagerModule.kt index c5bc28999b..ca45c78a6b 100644 --- a/core/featuretoggles/src/main/kotlin/com/tangem/core/featuretoggle/di/FeatureTogglesManagerModule.kt +++ b/core/featuretoggles/src/main/kotlin/com/tangem/core/featuretoggle/di/FeatureTogglesManagerModule.kt @@ -1,16 +1,13 @@ package com.tangem.core.featuretoggle.di import android.content.Context -import com.squareup.moshi.Moshi -import com.squareup.moshi.adapter -import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory import com.tangem.core.featuretoggle.manager.DevFeatureTogglesManager import com.tangem.core.featuretoggle.manager.FeatureTogglesManager import com.tangem.core.featuretoggle.manager.ProdFeatureTogglesManager import com.tangem.core.featuretoggle.storage.LocalFeatureTogglesStorage import com.tangem.core.featuretoggle.version.DefaultVersionProvider import com.tangem.core.featuretoggles.BuildConfig -import com.tangem.datasource.asset.reader.AssetReader +import com.tangem.datasource.asset.loader.AssetLoader import com.tangem.datasource.local.preferences.AppPreferencesStore import dagger.Module import dagger.Provides @@ -25,17 +22,12 @@ internal object FeatureTogglesManagerModule { @Provides @Singleton - @OptIn(ExperimentalStdlibApi::class) fun provideFeatureTogglesManager( @ApplicationContext context: Context, - assetReader: AssetReader, + assetLoader: AssetLoader, appPreferencesStore: AppPreferencesStore, ): FeatureTogglesManager { - val moshi = Moshi.Builder().addLast(KotlinJsonAdapterFactory()).build() - val localFeatureTogglesStorage = LocalFeatureTogglesStorage( - assetReader = assetReader, - jsonAdapter = moshi.adapter(), - ) + val localFeatureTogglesStorage = LocalFeatureTogglesStorage(assetLoader) val versionProvider = DefaultVersionProvider(context) return if (BuildConfig.TESTER_MENU_ENABLED) { diff --git a/core/featuretoggles/src/main/kotlin/com/tangem/core/featuretoggle/storage/LocalFeatureTogglesStorage.kt b/core/featuretoggles/src/main/kotlin/com/tangem/core/featuretoggle/storage/LocalFeatureTogglesStorage.kt index ad0f4f9939..dbd92dee48 100644 --- a/core/featuretoggles/src/main/kotlin/com/tangem/core/featuretoggle/storage/LocalFeatureTogglesStorage.kt +++ b/core/featuretoggles/src/main/kotlin/com/tangem/core/featuretoggle/storage/LocalFeatureTogglesStorage.kt @@ -1,42 +1,28 @@ package com.tangem.core.featuretoggle.storage -import androidx.annotation.VisibleForTesting -import com.squareup.moshi.JsonAdapter import com.tangem.core.featuretoggle.storage.LocalFeatureTogglesStorage.Companion.LOCAL_CONFIG_PATH -import com.tangem.datasource.asset.reader.AssetReader -import timber.log.Timber +import com.tangem.datasource.asset.loader.AssetLoader import kotlin.properties.Delegates /** * Storage implementation for storing local feature toggles. * Feature toggles are declared in file [LOCAL_CONFIG_PATH]. * - * @property assetReader asset reader - * @property jsonAdapter adapter for parsing local json config + * @property assetLoader asset loader * [REDACTED_AUTHOR] */ internal class LocalFeatureTogglesStorage( - private val assetReader: AssetReader, - private val jsonAdapter: JsonAdapter>, + private val assetLoader: AssetLoader, ) : FeatureTogglesStorage { override var featureToggles: List by Delegates.notNull() private set - @Deprecated(message = "Use AssetReader instead") override suspend fun init() { - runCatching { requireNotNull(jsonAdapter.fromJson(assetReader.readJson(LOCAL_CONFIG_PATH))) } - .onSuccess { featureToggles = it } - .onFailure { Timber.e(LocalFeatureTogglesStorage::class.java.name, "Failed to parse $LOCAL_CONFIG_PATH") } + featureToggles = assetLoader.loadList(LOCAL_CONFIG_PATH) } - @VisibleForTesting(otherwise = VisibleForTesting.NONE) - fun getConfigPath() = LOCAL_CONFIG_PATH - - @VisibleForTesting(otherwise = VisibleForTesting.NONE) - fun getFeatureToggles(): Iterable = featureToggles - private companion object { const val LOCAL_CONFIG_PATH: String = "configs/feature_toggles_config" } diff --git a/core/featuretoggles/src/test/kotlin/com/tangem/core/featuretoggle/storage/LocalFeatureTogglesStorageTest.kt b/core/featuretoggles/src/test/kotlin/com/tangem/core/featuretoggle/storage/LocalFeatureTogglesStorageTest.kt index 0f42883777..3950e2c649 100644 --- a/core/featuretoggles/src/test/kotlin/com/tangem/core/featuretoggle/storage/LocalFeatureTogglesStorageTest.kt +++ b/core/featuretoggles/src/test/kotlin/com/tangem/core/featuretoggle/storage/LocalFeatureTogglesStorageTest.kt @@ -3,11 +3,11 @@ package com.tangem.core.featuretoggle.storage import android.annotation.SuppressLint import com.google.common.truth.Truth import com.squareup.moshi.JsonAdapter +import com.squareup.moshi.Moshi +import com.squareup.moshi.Types +import com.tangem.datasource.asset.loader.AssetLoader import com.tangem.datasource.asset.reader.AssetReader -import io.mockk.coEvery -import io.mockk.mockk -import io.mockk.verifyAll -import io.mockk.verifyOrder +import io.mockk.* import kotlinx.coroutines.test.runTest import org.junit.Test import java.io.IOException @@ -19,70 +19,69 @@ import java.io.IOException internal class LocalFeatureTogglesStorageTest { private val assetReader = mockk() + private val moshi = mockk() private val jsonAdapter = mockk>>() - private val storage = LocalFeatureTogglesStorage(assetReader, jsonAdapter) + + // Impossible to mockk AssetLoader because it implement inline functions + private val assetLoader = AssetLoader(assetReader = assetReader, moshi = moshi) + + private val storage = LocalFeatureTogglesStorage(assetLoader) @Test fun `successfully initialize storage`() = runTest { - coEvery { assetReader.readJson(storage.getConfigPath()) } returns json - coEvery { jsonAdapter.fromJson(json) } returns featureToggles + everyReadingJson() returns json + everyCreatingMoshiAdapter() returns jsonAdapter + everyMappingJson() returns featureToggles storage.init() - verifyOrder { - assetReader.readJson(storage.getConfigPath()) + coVerifyOrder { + assetReader.read(CONFIG_FILE_NAME) jsonAdapter.fromJson(json) } - Truth.assertThat(storage.getFeatureToggles()).containsExactlyElementsIn(featureToggles) + Truth.assertThat(storage.featureToggles).containsExactlyElementsIn(featureToggles) } @Test fun `failure initialize storage if assetReader throws exception`() = runTest { - coEvery { assetReader.readJson(storage.getConfigPath()) } returns json - coEvery { jsonAdapter.fromJson(json) } throws IOException() + everyReadingJson() returns json + everyCreatingMoshiAdapter() returns jsonAdapter + everyMappingJson() throws IOException() storage.init() - verifyOrder { - assetReader.readJson(storage.getConfigPath()) + coVerifyOrder { + assetReader.read(CONFIG_FILE_NAME) jsonAdapter.fromJson(json) } - runCatching { storage.getFeatureToggles() } - .onSuccess { throw IllegalStateException("featureToggles shouldn't be initialized") } - .onFailure { - Truth - .assertThat(it) - .hasMessageThat() - .contains("Property featureToggles should be initialized before get.") - - Truth.assertThat(it).isInstanceOf(IllegalStateException::class.java) - } + Truth.assertThat(storage.featureToggles).containsExactlyElementsIn(emptyList()) } @Test fun `failure initialize storage if jsonAdapter throws exception`() = runTest { - coEvery { assetReader.readJson(storage.getConfigPath()) } throws IOException() + everyReadingJson() throws IOException() storage.init() - verifyOrder { assetReader.readJson(storage.getConfigPath()) } + coVerifyOrder { assetReader.read(CONFIG_FILE_NAME) } verifyAll(inverse = true) { jsonAdapter.fromJson(any()) } - runCatching { storage.getFeatureToggles() } - .onSuccess { throw IllegalStateException("featureToggles shouldn't be initialized") } - .onFailure { - Truth - .assertThat(it) - .hasMessageThat() - .contains("Property featureToggles should be initialized before get.") - - Truth.assertThat(it).isInstanceOf(IllegalStateException::class.java) - } + Truth.assertThat(storage.featureToggles).containsExactlyElementsIn(emptyList()) } + private fun everyReadingJson() = coEvery { assetReader.read(CONFIG_FILE_NAME) } + + private fun everyCreatingMoshiAdapter() = every { + val types = Types.newParameterizedType(List::class.java, FeatureToggle::class.java) + moshi.adapter>(types) + } + + private fun everyMappingJson() = every { jsonAdapter.fromJson(json) } + private companion object { + const val CONFIG_FILE_NAME = "configs/feature_toggles_config.json" val json = """ [ diff --git a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/DefaultWalletManagersFacade.kt b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/DefaultWalletManagersFacade.kt index c63725cdc2..1b0637dbd7 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/DefaultWalletManagersFacade.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/DefaultWalletManagersFacade.kt @@ -4,7 +4,6 @@ import arrow.core.Either import arrow.core.raise.either import arrow.core.raise.ensureNotNull import arrow.core.right -import com.squareup.moshi.Moshi import com.tangem.blockchain.blockchains.solana.RentProvider import com.tangem.blockchain.common.* import com.tangem.blockchain.common.address.Address @@ -19,7 +18,7 @@ import com.tangem.blockchain.extensions.Result import com.tangem.blockchain.extensions.SimpleResult import com.tangem.blockchainsdk.BlockchainSDKFactory import com.tangem.crypto.hdWallet.DerivationPath -import com.tangem.datasource.asset.reader.AssetReader +import com.tangem.datasource.asset.loader.AssetLoader import com.tangem.datasource.local.userwallet.UserWalletsStore import com.tangem.datasource.local.walletmanager.WalletManagersStore import com.tangem.domain.common.util.hasDerivation @@ -31,6 +30,7 @@ import com.tangem.domain.transaction.models.AssetRequirementsCondition import com.tangem.domain.txhistory.models.PaginationWrapper import com.tangem.domain.txhistory.models.TxHistoryItem import com.tangem.domain.txhistory.models.TxHistoryState +import com.tangem.domain.walletmanager.model.SmartContractMethod import com.tangem.domain.walletmanager.model.UpdateWalletManagerResult import com.tangem.domain.walletmanager.utils.* import com.tangem.domain.walletmanager.utils.WalletManagerFactory @@ -47,8 +47,7 @@ import java.util.EnumSet class DefaultWalletManagersFacade( private val walletManagersStore: WalletManagersStore, private val userWalletsStore: UserWalletsStore, - assetReader: AssetReader, - moshi: Moshi, + private val assetLoader: AssetLoader, blockchainSDKFactory: BlockchainSDKFactory, ) : WalletManagersFacade { @@ -57,7 +56,6 @@ class DefaultWalletManagersFacade( 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) } private val sdkPageConverter by lazy { SdkPageConverter() } private val cryptoCurrencyTypeConverter by lazy { CryptoCurrencyTypeConverter() } private val requirementsConditionConverter by lazy { SdkRequirementsConditionConverter() } @@ -236,7 +234,8 @@ class DefaultWalletManagersFacade( is Result.Success -> PaginationWrapper( currentPage = sdkPageConverter.convert(page), nextPage = sdkPageConverter.convert(itemsResult.data.nextPage), - items = txHistoryItemConverter.convertList(itemsResult.data.items), + items = SdkTransactionHistoryItemConverter(smartContractMethods = readSmartContractMethods()) + .convertList(itemsResult.data.items), ) is Result.Failure -> error(itemsResult.error.message ?: itemsResult.error.customMessage) } @@ -616,4 +615,8 @@ class DefaultWalletManagersFacade( walletManager.addTokens(tokensToAdd) } + + private suspend fun readSmartContractMethods(): Map { + return assetLoader.loadMap(fileName = "contract_methods") + } } \ No newline at end of file diff --git a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/utils/SdkTransactionHistoryItemConverter.kt b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/utils/SdkTransactionHistoryItemConverter.kt index 2e1fba8fe9..5999db6ea0 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/utils/SdkTransactionHistoryItemConverter.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/utils/SdkTransactionHistoryItemConverter.kt @@ -1,20 +1,16 @@ package com.tangem.domain.walletmanager.utils -import com.squareup.moshi.Moshi import com.tangem.blockchain.common.txhistory.TransactionHistoryItem -import com.tangem.datasource.asset.reader.AssetReader import com.tangem.domain.txhistory.models.TxHistoryItem +import com.tangem.domain.walletmanager.model.SmartContractMethod import com.tangem.utils.converter.Converter import com.tangem.blockchain.common.txhistory.TransactionHistoryItem as SdkTransactionHistoryItem internal class SdkTransactionHistoryItemConverter( - assetReader: AssetReader, - moshi: Moshi, + smartContractMethods: Map, ) : Converter { - private val typeConverter by lazy { - SdkTransactionTypeConverter(assetReader, moshi) - } + private val typeConverter by lazy { SdkTransactionTypeConverter(smartContractMethods) } override fun convert(value: SdkTransactionHistoryItem): TxHistoryItem = TxHistoryItem( txHash = value.txHash, diff --git a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/utils/SdkTransactionTypeConverter.kt b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/utils/SdkTransactionTypeConverter.kt index ac4402be26..a416bf6085 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/utils/SdkTransactionTypeConverter.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/utils/SdkTransactionTypeConverter.kt @@ -1,30 +1,14 @@ package com.tangem.domain.walletmanager.utils -import com.squareup.moshi.JsonAdapter -import com.squareup.moshi.Moshi -import com.squareup.moshi.Types import com.tangem.blockchain.common.txhistory.TransactionHistoryItem -import com.tangem.datasource.asset.reader.AssetReader import com.tangem.domain.txhistory.models.TxHistoryItem import com.tangem.domain.walletmanager.model.SmartContractMethod import com.tangem.utils.converter.Converter internal class SdkTransactionTypeConverter( - private val assetReader: AssetReader, - private val moshi: Moshi, + private val smartContractMethods: Map, ) : Converter { - private val adapter: JsonAdapter> by lazy { - moshi.adapter( - Types.newParameterizedType( - Map::class.java, - String::class.java, - SmartContractMethod::class.java, - ), - ) - } - private val smartContractMethods by lazy { readSmartContractMethods() } - override fun convert(value: TransactionHistoryItem.TransactionType): TxHistoryItem.TransactionType { return when (value) { is TransactionHistoryItem.TransactionType.ContractMethod -> @@ -43,9 +27,4 @@ internal class SdkTransactionTypeConverter( else -> TxHistoryItem.TransactionType.Operation(name = methodName.replaceFirstChar { it.titlecase() }) } } - - private fun readSmartContractMethods(): Map { - val json = assetReader.readJson("contract_methods") - return adapter.fromJson(json) ?: emptyMap() - } } \ No newline at end of file