From b601aea5c340caf99c3d2b39f64acd22e4767c65 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 16 Apr 2024 16:01:41 +0800 Subject: [PATCH] Updated on 2026-08-14 --- app/src/main/assets/tangem-app-config | 2 +- .../datasource/config/ConfigManagerImpl.kt | 2 + .../datasource/config/models/JsonModels.kt | 2 + gradle/dependencies.toml | 2 +- .../DefaultBlockchainSDKFactory.kt | 67 ++++++++++++++----- .../blockchainsdk/config/ConfigStorage.kt | 18 ----- .../config/RuntimeConfigStorage.kt | 21 ------ .../BlockchainProviderTypesConverter.kt | 64 ++++++++++++++++++ .../BlockchainSDKConfigConverter.kt | 2 + .../di/BlockchainSDKFactoryModule.kt | 6 +- .../storage/DefaultRuntimeStore.kt | 20 ++++++ .../blockchainsdk/storage/RuntimeStore.kt | 17 +++++ .../tangem/blockchainsdk/utils/Blockchain.kt | 7 ++ 13 files changed, 172 insertions(+), 58 deletions(-) delete mode 100644 libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/config/ConfigStorage.kt delete mode 100644 libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/config/RuntimeConfigStorage.kt create mode 100644 libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/converters/BlockchainProviderTypesConverter.kt create mode 100644 libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/storage/DefaultRuntimeStore.kt create mode 100644 libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/storage/RuntimeStore.kt diff --git a/app/src/main/assets/tangem-app-config b/app/src/main/assets/tangem-app-config index b098560072..367aa6465e 160000 --- a/app/src/main/assets/tangem-app-config +++ b/app/src/main/assets/tangem-app-config @@ -1 +1 @@ -Subproject commit b0985600722953fae0a93bcbbc2a83930b9e0cbe +Subproject commit 367aa6465ec6ee7fdccce6cc7d7abeed5aad1111 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 8ebac44c3b..ba04ed3f0f 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 @@ -146,6 +146,8 @@ internal class ConfigManagerImpl @Inject constructor() : ConfigManager { blockBookRest = accessTokens.bitcoin?.blockBookRest, ), algorand = GetBlockAccessToken(rest = accessTokens.algorand?.rest), + zkSyncEra = GetBlockAccessToken(jsonRpc = accessTokens.zksync?.jsonRPC), + polygonZkEvm = GetBlockAccessToken(jsonRpc = accessTokens.polygonZkevm?.jsonRPC), ) } } diff --git a/core/datasource/src/main/java/com/tangem/datasource/config/models/JsonModels.kt b/core/datasource/src/main/java/com/tangem/datasource/config/models/JsonModels.kt index 2a79daad20..417d8f8b73 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/config/models/JsonModels.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/config/models/JsonModels.kt @@ -68,6 +68,8 @@ data class GetBlockAccessTokens( @Json(name = "dash") val dash: GetBlockToken?, @Json(name = "bitcoin") val bitcoin: GetBlockToken?, @Json(name = "algorand") val algorand: GetBlockToken?, + @Json(name = "polygon-zkevm") val polygonZkevm: GetBlockToken?, + @Json(name = "zksync") val zksync: GetBlockToken?, ) @JsonClass(generateAdapter = true) diff --git a/gradle/dependencies.toml b/gradle/dependencies.toml index eab18a906d..80d6ea518d 100644 --- a/gradle/dependencies.toml +++ b/gradle/dependencies.toml @@ -85,7 +85,7 @@ leakcanary = "2.13" # endregion Other libraries # region Tangem -tangemBlockchainSdk = "develop-576" +tangemBlockchainSdk = "develop-593" #tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds tangemCardSdk = "develop-339" #tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^ diff --git a/libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/DefaultBlockchainSDKFactory.kt b/libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/DefaultBlockchainSDKFactory.kt index 891dbc65b8..2a18ece1dc 100644 --- a/libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/DefaultBlockchainSDKFactory.kt +++ b/libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/DefaultBlockchainSDKFactory.kt @@ -1,32 +1,45 @@ package com.tangem.blockchainsdk import com.tangem.blockchain.common.AccountCreator +import com.tangem.blockchain.common.Blockchain +import com.tangem.blockchain.common.BlockchainSdkConfig import com.tangem.blockchain.common.WalletManagerFactory import com.tangem.blockchain.common.datastorage.BlockchainDataStorage import com.tangem.blockchain.common.logging.BlockchainSDKLogger -import com.tangem.blockchainsdk.config.ConfigStorage +import com.tangem.blockchain.common.network.providers.ProviderType +import com.tangem.blockchainsdk.converters.BlockchainProviderTypesConverter import com.tangem.blockchainsdk.converters.BlockchainSDKConfigConverter +import com.tangem.blockchainsdk.storage.RuntimeStore import com.tangem.datasource.asset.loader.AssetLoader import com.tangem.datasource.config.models.ConfigValueModel +import com.tangem.datasource.config.models.ProviderModel import com.tangem.libs.blockchain_sdk.BuildConfig +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.firstOrNull -import kotlinx.coroutines.flow.map +import kotlinx.coroutines.launch + +internal typealias BlockchainProvidersResponse = Map> +internal typealias BlockchainProviderTypes = Map> /** * Implementation of Blockchain SDK components factory * - * @property assetLoader asset loader - * @property configStorage config storage - * @property accountCreator account creator - * @property blockchainDataStorage blockchain data storage - * @property blockchainSDKLogger blockchain SDK logger + * @property assetLoader asset loader + * @property configStore blockchain sdk config store + * @property blockchainProviderTypesStore blockchain provider types store + * @property accountCreator account creator + * @property blockchainDataStorage blockchain data storage + * @property blockchainSDKLogger blockchain SDK logger * [REDACTED_AUTHOR] */ internal class DefaultBlockchainSDKFactory( private val assetLoader: AssetLoader, - private val configStorage: ConfigStorage, + private val configStore: RuntimeStore, + private val blockchainProviderTypesStore: RuntimeStore, private val accountCreator: AccountCreator, private val blockchainDataStorage: BlockchainDataStorage, private val blockchainSDKLogger: BlockchainSDKLogger, @@ -35,19 +48,22 @@ internal class DefaultBlockchainSDKFactory( override val walletManagerFactory: Flow by lazy(::createWalletManagerFactory) override suspend fun init() { - val configValueModel = assetLoader.load(CONFIG_FILE_NAME) ?: return - - configStorage.store( - config = BlockchainSDKConfigConverter.convert(value = configValueModel), - ) + coroutineScope { + updateBlockchainSDKConfig() + updateBlockchainProviderTypes() + } } override suspend fun getWalletManagerFactorySync(): WalletManagerFactory? = walletManagerFactory.firstOrNull() private fun createWalletManagerFactory(): Flow { - return configStorage.get().map { config -> + return combine( + flow = configStore.get(), + flow2 = blockchainProviderTypesStore.get(), + ) { config, blockchainProviderTypes -> WalletManagerFactory( config = config, + blockchainProviderTypes = blockchainProviderTypes, accountCreator = accountCreator, blockchainDataStorage = blockchainDataStorage, loggers = listOf(blockchainSDKLogger), @@ -55,8 +71,29 @@ internal class DefaultBlockchainSDKFactory( } } - private companion object { + private fun CoroutineScope.updateBlockchainSDKConfig() { + launch { + val config = assetLoader.load(fileName = CONFIG_FILE_NAME) ?: return@launch + configStore.store( + value = BlockchainSDKConfigConverter.convert(value = config), + ) + } + } + + private fun CoroutineScope.updateBlockchainProviderTypes() { + launch { + val providerTypes = assetLoader.load(fileName = PROVIDER_TYPES_FILE_NAME) + ?: return@launch + + blockchainProviderTypesStore.store( + value = BlockchainProviderTypesConverter.convert(providerTypes), + ) + } + } + + private companion object { const val CONFIG_FILE_NAME = "tangem-app-config/config_${BuildConfig.ENVIRONMENT}" + const val PROVIDER_TYPES_FILE_NAME = "tangem-app-config/providers_order" } } \ No newline at end of file diff --git a/libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/config/ConfigStorage.kt b/libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/config/ConfigStorage.kt deleted file mode 100644 index e9aaaf807b..0000000000 --- a/libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/config/ConfigStorage.kt +++ /dev/null @@ -1,18 +0,0 @@ -package com.tangem.blockchainsdk.config - -import com.tangem.blockchain.common.BlockchainSdkConfig -import kotlinx.coroutines.flow.Flow - -/** - * Storage for [BlockchainSdkConfig] - * -[REDACTED_AUTHOR] - */ -internal interface ConfigStorage { - - /** Get flow of [BlockchainSdkConfig] */ - fun get(): Flow - - /** Store [BlockchainSdkConfig] */ - suspend fun store(config: BlockchainSdkConfig) -} \ No newline at end of file diff --git a/libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/config/RuntimeConfigStorage.kt b/libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/config/RuntimeConfigStorage.kt deleted file mode 100644 index 0adb68868e..0000000000 --- a/libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/config/RuntimeConfigStorage.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.tangem.blockchainsdk.config - -import com.tangem.blockchain.common.BlockchainSdkConfig -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.MutableStateFlow - -/** - * Runtime storage for [BlockchainSdkConfig] - * -[REDACTED_AUTHOR] - */ -internal class RuntimeConfigStorage : ConfigStorage { - - private val configFlow = MutableStateFlow(value = BlockchainSdkConfig()) - - override fun get(): Flow = configFlow - - override suspend fun store(config: BlockchainSdkConfig) { - configFlow.value = config - } -} \ No newline at end of file diff --git a/libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/converters/BlockchainProviderTypesConverter.kt b/libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/converters/BlockchainProviderTypesConverter.kt new file mode 100644 index 0000000000..2a2e2a42f9 --- /dev/null +++ b/libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/converters/BlockchainProviderTypesConverter.kt @@ -0,0 +1,64 @@ +package com.tangem.blockchainsdk.converters + +import com.tangem.blockchain.common.Blockchain +import com.tangem.blockchain.common.network.providers.ProviderType +import com.tangem.blockchainsdk.BlockchainProviderTypes +import com.tangem.blockchainsdk.BlockchainProvidersResponse +import com.tangem.blockchainsdk.utils.fromNetworkId +import com.tangem.datasource.config.models.ProviderModel +import com.tangem.utils.converter.Converter +import timber.log.Timber + +/** + * Converts [BlockchainProvidersResponse] to [BlockchainProviderTypes] + * +[REDACTED_AUTHOR] + */ +internal object BlockchainProviderTypesConverter : + Converter { + + override fun convert(value: BlockchainProvidersResponse): BlockchainProviderTypes { + return value.mapNotNull { (networkId, blockchainProviders) -> + val blockchain = Blockchain.fromNetworkId(networkId) ?: return@mapNotNull null + + val providerTypes = blockchainProviders.mapNotNull { provider -> + when (provider) { + is ProviderModel.Public -> ProviderType.Public(url = provider.url) + is ProviderModel.Private -> createPrivateProviderType(blockchain = blockchain, name = provider.name) + ProviderModel.UnsupportedType -> { + Timber.e("$blockchain provider type is not supported") + null + } + } + } + + blockchain to providerTypes + } + .toMap() + } + + @Suppress("CyclomaticComplexMethod") + private fun createPrivateProviderType(blockchain: Blockchain, name: String): ProviderType? { + return when (name) { + "blockchair" -> ProviderType.BitcoinLike.Blockchair + "blockcypher" -> ProviderType.BitcoinLike.Blockcypher + "adalite" -> ProviderType.Cardano.Adalite + "tangemRosetta" -> ProviderType.Cardano.Rosetta + "fireAcademy" -> ProviderType.Chia.FireAcademy + "tangemChia" -> ProviderType.Chia.Tangem + "infura" -> ProviderType.EthereumLike.Infura + "getblock" -> ProviderType.GetBlock + "arkhiaHedera" -> ProviderType.Hedera.Arkhia + "kaspa" -> ProviderType.Kaspa.SecondaryAPI + "nownodes" -> ProviderType.NowNodes + "quicknode" -> ProviderType.QuickNode + "solana" -> ProviderType.Solana.Official + "ton" -> ProviderType.Ton.TonCentral + "tron" -> ProviderType.Tron.TronGrid + else -> { + Timber.e("$blockchain private provider ($name) is not supported") + null + } + } + } +} \ No newline at end of file diff --git a/libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/converters/BlockchainSDKConfigConverter.kt b/libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/converters/BlockchainSDKConfigConverter.kt index d7551a2eea..17d38bd0c6 100644 --- a/libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/converters/BlockchainSDKConfigConverter.kt +++ b/libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/converters/BlockchainSDKConfigConverter.kt @@ -77,6 +77,8 @@ internal object BlockchainSDKConfigConverter : Converter(defaultValue: T) : RuntimeStore { + + private val flow = MutableStateFlow(value = defaultValue) + + override fun get(): StateFlow = flow + + override suspend fun store(value: T) { + flow.value = value + } +} \ No newline at end of file diff --git a/libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/storage/RuntimeStore.kt b/libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/storage/RuntimeStore.kt new file mode 100644 index 0000000000..a3de160654 --- /dev/null +++ b/libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/storage/RuntimeStore.kt @@ -0,0 +1,17 @@ +package com.tangem.blockchainsdk.storage + +import kotlinx.coroutines.flow.StateFlow + +/** + * Runtime store + * +[REDACTED_AUTHOR] + */ +internal interface RuntimeStore { + + /** Get flow of elements [T] */ + fun get(): StateFlow + + /** Store [value] */ + suspend fun store(value: T) +} \ No newline at end of file diff --git a/libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/utils/Blockchain.kt b/libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/utils/Blockchain.kt index 2d011e9af9..cd181cb4c1 100644 --- a/libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/utils/Blockchain.kt +++ b/libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/utils/Blockchain.kt @@ -114,6 +114,8 @@ fun Blockchain.Companion.fromNetworkId(networkId: String): Blockchain? { "taraxa/test" -> Blockchain.TaraxaTestnet "base" -> Blockchain.Base "base/test" -> Blockchain.BaseTestnet + "koinos" -> Blockchain.Koinos + "koinos/test" -> Blockchain.KoinosTestnet else -> null } } @@ -229,6 +231,8 @@ fun Blockchain.toNetworkId(): String { Blockchain.TaraxaTestnet -> "taraxa/test" Blockchain.Base -> "base" Blockchain.BaseTestnet -> "base/test" + Blockchain.Koinos -> "koinos" + Blockchain.KoinosTestnet -> "koinos/test" } } @@ -302,6 +306,7 @@ fun Blockchain.toCoinId(): String { Blockchain.Flare, Blockchain.FlareTestnet -> "flare-networks" Blockchain.Taraxa, Blockchain.TaraxaTestnet -> "taraxa" Blockchain.Base, Blockchain.BaseTestnet -> "base" + Blockchain.Koinos, Blockchain.KoinosTestnet -> "koinos" } } @@ -332,4 +337,6 @@ private val excludedBlockchains = listOf( Blockchain.Nexa, Blockchain.NexaTestnet, Blockchain.Radiant, + Blockchain.Koinos, + Blockchain.KoinosTestnet, ) \ No newline at end of file