Updated on 2026-08-14
This commit is contained in:
parent
950dc41662
commit
dfa6798f07
16 changed files with 220 additions and 82 deletions
|
|
@ -3,7 +3,6 @@ package com.tangem.blockchainsdk.providers
|
|||
import androidx.core.util.PatternsCompat
|
||||
import com.google.firebase.crashlytics.FirebaseCrashlytics
|
||||
import com.tangem.blockchainsdk.BlockchainProvidersResponse
|
||||
import com.tangem.blockchainsdk.utils.createPrivateProviderType
|
||||
import com.tangem.datasource.local.config.providers.models.ProviderModel
|
||||
import timber.log.Timber
|
||||
|
||||
|
|
@ -48,11 +47,11 @@ internal object BlockchainProvidersResponseMerger {
|
|||
return result.guaranteeUrlsEndWithSlash()
|
||||
}
|
||||
|
||||
private fun List<ProviderModel>.filterUnsupportedProviders() = filter {
|
||||
val isSupportedType = it !is ProviderModel.UnsupportedType
|
||||
private fun List<ProviderModel>.filterUnsupportedProviders() = filter { model ->
|
||||
val isSupportedType = model !is ProviderModel.UnsupportedType
|
||||
|
||||
val isSupportedPrivateType = if (it is ProviderModel.Private) {
|
||||
createPrivateProviderType(it.name) != null
|
||||
val isSupportedPrivateType = if (model is ProviderModel.Private) {
|
||||
ProviderTypeIdMapping.entries.any { it.id == model.name }
|
||||
} else {
|
||||
true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
package com.tangem.blockchainsdk.providers
|
||||
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
/** Blockchain providers types manager */
|
||||
interface BlockchainProvidersTypesManager {
|
||||
|
||||
fun get(): StateFlow<BlockchainProviderTypes>
|
||||
fun get(): Flow<BlockchainProviderTypes>
|
||||
|
||||
suspend fun update()
|
||||
}
|
||||
|
|
@ -1,45 +1,68 @@
|
|||
package com.tangem.blockchainsdk.providers
|
||||
|
||||
import androidx.datastore.core.DataStore
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.network.providers.ProviderType
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
import kotlin.properties.Delegates.notNull
|
||||
import com.tangem.blockchainsdk.BlockchainProvidersResponse
|
||||
import com.tangem.blockchainsdk.converters.BlockchainProviderTypesConverter
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import kotlinx.coroutines.flow.map
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
* Implementation of [BlockchainProvidersTypesManager] in DEV environment
|
||||
*
|
||||
* @property prodBlockchainProvidersTypesManager prod manager
|
||||
* @property blockchainProviderTypesStore blockchain provider types store
|
||||
* @property changedBlockchainProvidersStore changed blockchain providers store
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@Singleton
|
||||
internal class DevBlockchainProvidersTypesManager @Inject constructor(
|
||||
internal class DevBlockchainProvidersTypesManager(
|
||||
private val prodBlockchainProvidersTypesManager: ProdBlockchainProvidersTypesManager,
|
||||
private val blockchainProviderTypesStore: BlockchainProviderTypesStore,
|
||||
) : BlockchainProvidersTypesManager by prodBlockchainProvidersTypesManager,
|
||||
MutableBlockchainProvidersTypesManager {
|
||||
private val changedBlockchainProvidersStore: DataStore<BlockchainProvidersResponse>,
|
||||
) : MutableBlockchainProvidersTypesManager {
|
||||
|
||||
private var primaryResponse: BlockchainProviderTypes by notNull()
|
||||
override fun get(): Flow<BlockchainProviderTypes> = changedBlockchainProvidersStore.data
|
||||
.map(BlockchainProviderTypesConverter::convert)
|
||||
|
||||
override suspend fun update() {
|
||||
prodBlockchainProvidersTypesManager.update()
|
||||
|
||||
primaryResponse = blockchainProviderTypesStore.get().value
|
||||
val initial = blockchainProviderTypesStore.get().value
|
||||
|
||||
val changed = changedBlockchainProvidersStore.data.firstOrNull().orEmpty()
|
||||
|
||||
if (changed.isEmpty()) {
|
||||
Timber.i("Initialize ChangedBlockchainProvidersStore")
|
||||
changedBlockchainProvidersStore.updateData {
|
||||
BlockchainProviderTypesConverter.convertBack(initial)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun recoverInitialState() {
|
||||
val initial = blockchainProviderTypesStore.get().value
|
||||
|
||||
changedBlockchainProvidersStore.updateData {
|
||||
BlockchainProviderTypesConverter.convertBack(initial)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun update(blockchain: Blockchain, providers: List<ProviderType>) {
|
||||
val currentTypes = blockchainProviderTypesStore.get().value
|
||||
changedBlockchainProvidersStore.updateData {
|
||||
val providerModels = BlockchainProviderTypesConverter.convertBack(value = mapOf(blockchain to providers))
|
||||
|
||||
val updatedTypes = currentTypes + (blockchain to providers)
|
||||
|
||||
blockchainProviderTypesStore.store(value = updatedTypes)
|
||||
it + providerModels
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun isMatchWithMerged(): Boolean {
|
||||
val current = blockchainProviderTypesStore.get().value
|
||||
val initial = blockchainProviderTypesStore.get().value
|
||||
val changed = changedBlockchainProvidersStore.data.firstOrNull().orEmpty()
|
||||
|
||||
return current == primaryResponse
|
||||
return initial == BlockchainProviderTypesConverter.convert(changed)
|
||||
}
|
||||
}
|
||||
|
|
@ -13,6 +13,9 @@ interface MutableBlockchainProvidersTypesManager : BlockchainProvidersTypesManag
|
|||
/** Update [providers] for [blockchain] */
|
||||
suspend fun update(blockchain: Blockchain, providers: List<ProviderType>)
|
||||
|
||||
/** Recover initial state */
|
||||
suspend fun recoverInitialState()
|
||||
|
||||
/** Checks that current [BlockchainProviderTypes] was changed */
|
||||
suspend fun isMatchWithMerged(): Boolean
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
package com.tangem.blockchainsdk.providers
|
||||
|
||||
import com.tangem.blockchainsdk.converters.BlockchainProviderTypesConverter
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
|
@ -20,7 +20,7 @@ internal class ProdBlockchainProvidersTypesManager @Inject constructor(
|
|||
private val blockchainProviderTypesStore: BlockchainProviderTypesStore,
|
||||
) : BlockchainProvidersTypesManager {
|
||||
|
||||
override fun get(): StateFlow<BlockchainProviderTypes> = blockchainProviderTypesStore.get()
|
||||
override fun get(): Flow<BlockchainProviderTypes> = blockchainProviderTypesStore.get()
|
||||
|
||||
override suspend fun update() {
|
||||
val response = blockchainProvidersResponseLoader.load()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
package com.tangem.blockchainsdk.providers
|
||||
|
||||
import com.tangem.blockchain.common.network.providers.ProviderType
|
||||
|
||||
/** Mapping of [providerType] with [id] */
|
||||
internal enum class ProviderTypeIdMapping(val id: String, val providerType: ProviderType) {
|
||||
NowNodes(id = "nownodes", providerType = ProviderType.NowNodes),
|
||||
GetBlock(id = "getblock", providerType = ProviderType.GetBlock),
|
||||
QuickNode(id = "quicknode", providerType = ProviderType.QuickNode),
|
||||
BitcoinBlockchair(id = "blockchair", providerType = ProviderType.BitcoinLike.Blockchair),
|
||||
BitcoinBlockcypher(id = "blockcypher", providerType = ProviderType.BitcoinLike.Blockcypher),
|
||||
CardanoAdalite(id = "adalite", providerType = ProviderType.Cardano.Adalite),
|
||||
CardanoRosetta(id = "tangemRosetta", providerType = ProviderType.Cardano.Rosetta),
|
||||
ChiaFireAcademy(id = "fireAcademy", providerType = ProviderType.Chia.FireAcademy),
|
||||
ChiaTangem(id = "tangemChia", providerType = ProviderType.Chia.Tangem),
|
||||
ChiaTangemNew(id = "tangemChia3", providerType = ProviderType.Chia.TangemNew),
|
||||
EthereumInfura(id = "infura", providerType = ProviderType.EthereumLike.Infura),
|
||||
HederaArkhia(id = "arkhiaHedera", providerType = ProviderType.Hedera.Arkhia),
|
||||
KaspaSecondary(id = "kaspa", providerType = ProviderType.Kaspa.SecondaryAPI),
|
||||
SolanaOfficial(id = "solana", providerType = ProviderType.Solana.Official),
|
||||
TonCentral(id = "ton", providerType = ProviderType.Ton.TonCentral),
|
||||
TronGrid(id = "tron", providerType = ProviderType.Tron.TronGrid),
|
||||
BittensorDwellir(id = "dwellirBittensor", providerType = ProviderType.Bittensor.Dwellir),
|
||||
BittensorOnfinality(id = "onfinalityBittensor", providerType = ProviderType.Bittensor.Onfinality),
|
||||
KoinosPro(id = "koinospro", providerType = ProviderType.Koinos.KoinosPro),
|
||||
;
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package com.tangem.blockchainsdk.providers.dev
|
||||
|
||||
import androidx.datastore.core.Serializer
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.squareup.moshi.Types
|
||||
import com.tangem.blockchainsdk.BlockchainProvidersResponse
|
||||
import com.tangem.datasource.local.config.providers.models.ProviderModel
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
|
||||
/** DataStore serializer for [BlockchainProvidersResponse]. Implemented by [Moshi]. */
|
||||
internal class BlockchainProvidersResponseSerializer(moshi: Moshi) : Serializer<BlockchainProvidersResponse> {
|
||||
|
||||
private val adapter by lazy {
|
||||
val providersType = Types.newParameterizedType(List::class.java, ProviderModel::class.java)
|
||||
val type = Types.newParameterizedType(Map::class.java, String::class.java, providersType)
|
||||
|
||||
moshi.adapter<BlockchainProvidersResponse>(type)
|
||||
}
|
||||
|
||||
override val defaultValue: BlockchainProvidersResponse = emptyMap()
|
||||
|
||||
override suspend fun readFrom(input: InputStream): BlockchainProvidersResponse {
|
||||
return input.bufferedReader().use { reader ->
|
||||
adapter.fromJson(reader.readText()) ?: defaultValue
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun writeTo(t: BlockchainProvidersResponse, output: OutputStream) {
|
||||
output.bufferedWriter().use { writer ->
|
||||
writer.write(adapter.toJson(t))
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue