Updated on 2026-08-14
This commit is contained in:
parent
463e5b1d52
commit
2a61e32f0c
4 changed files with 57 additions and 11 deletions
|
|
@ -1 +1 @@
|
|||
Subproject commit 367aa6465ec6ee7fdccce6cc7d7abeed5aad1111
|
||||
Subproject commit fdf0660901442ade296db42bb867fc5c16a14262
|
||||
|
|
@ -31,11 +31,11 @@ class AssetLoader @Inject constructor(
|
|||
}
|
||||
.fold(
|
||||
onSuccess = { parsedConfig ->
|
||||
if (parsedConfig == null) Timber.e(IllegalStateException("Parsed config is null"))
|
||||
if (parsedConfig == null) Timber.e(IllegalStateException("Parsed config [$fileName] is null"))
|
||||
parsedConfig
|
||||
},
|
||||
onFailure = {
|
||||
Timber.e(it, "Failed to load config from assets")
|
||||
Timber.e(it, "Failed to load config [$fileName] from assets")
|
||||
null
|
||||
},
|
||||
)
|
||||
|
|
@ -53,11 +53,11 @@ class AssetLoader @Inject constructor(
|
|||
}
|
||||
.fold(
|
||||
onSuccess = { parsedConfig ->
|
||||
if (parsedConfig == null) Timber.e(IllegalStateException("Parsed config is null"))
|
||||
if (parsedConfig == null) Timber.e(IllegalStateException("Parsed config [$fileName] is null"))
|
||||
parsedConfig.orEmpty()
|
||||
},
|
||||
onFailure = {
|
||||
Timber.e(it, "Failed to load config from assets")
|
||||
Timber.e(it, "Failed to load config [$fileName] from assets")
|
||||
emptyList()
|
||||
},
|
||||
)
|
||||
|
|
@ -75,11 +75,11 @@ class AssetLoader @Inject constructor(
|
|||
}
|
||||
.fold(
|
||||
onSuccess = { parsedConfig ->
|
||||
if (parsedConfig == null) Timber.e(IllegalStateException("Parsed config is null"))
|
||||
if (parsedConfig == null) Timber.e(IllegalStateException("Parsed config [$fileName] is null"))
|
||||
parsedConfig.orEmpty()
|
||||
},
|
||||
onFailure = {
|
||||
Timber.e(it, "Failed to load config from assets")
|
||||
Timber.e(it, "Failed to load config [$fileName] from assets")
|
||||
emptyMap()
|
||||
},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -32,6 +32,12 @@ dependencies {
|
|||
implementation(deps.timber)
|
||||
// endregion
|
||||
|
||||
// region Firebase libraries
|
||||
implementation(platform(deps.firebase.bom))
|
||||
implementation(deps.firebase.analytics)
|
||||
implementation(deps.firebase.crashlytics)
|
||||
// endregion
|
||||
|
||||
// region Tangem libraries
|
||||
implementation(deps.tangem.blockchain) { exclude(module = "joda-time") }
|
||||
implementation(deps.tangem.card.core)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.blockchainsdk.loader
|
||||
|
||||
import com.google.firebase.crashlytics.FirebaseCrashlytics
|
||||
import com.tangem.blockchainsdk.BlockchainProvidersResponse
|
||||
import com.tangem.datasource.api.common.AuthProvider
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechServiceApi
|
||||
|
|
@ -28,18 +29,26 @@ internal class BlockchainProvidersResponseLoader @Inject constructor(
|
|||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
) {
|
||||
|
||||
private val firebaseCrashlytics by lazy(FirebaseCrashlytics::getInstance)
|
||||
|
||||
/** Load [BlockchainProvidersResponse] */
|
||||
suspend fun load(): BlockchainProvidersResponse? {
|
||||
val localResponse = loadLocal() ?: return null
|
||||
|
||||
return runCatching(dispatcher = dispatchers.io, block = ::loadRemote)
|
||||
.fold(
|
||||
onSuccess = { it },
|
||||
onSuccess = { remoteResponse -> mergeResponses(local = localResponse, remote = remoteResponse) },
|
||||
onFailure = {
|
||||
Timber.e(it, "Failed to load blockchain provider types from backend")
|
||||
loadLocal()
|
||||
localResponse
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun loadLocal(): BlockchainProvidersResponse? {
|
||||
return assetLoader.load<BlockchainProvidersResponse>(fileName = PROVIDER_TYPES_FILE_NAME)
|
||||
}
|
||||
|
||||
private suspend fun loadRemote(): BlockchainProvidersResponse {
|
||||
return tangemTechServiceApi.getBlockchainProviders(
|
||||
cardPublicKey = authProvider.getCardPublicKey(),
|
||||
|
|
@ -47,8 +56,39 @@ internal class BlockchainProvidersResponseLoader @Inject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
private suspend fun loadLocal(): BlockchainProvidersResponse? {
|
||||
return assetLoader.load<BlockchainProvidersResponse>(fileName = PROVIDER_TYPES_FILE_NAME)
|
||||
/** Merge blockchains with non-empty providers [remote] from remote with blockchains from local [local] */
|
||||
private fun mergeResponses(
|
||||
local: BlockchainProvidersResponse,
|
||||
remote: BlockchainProvidersResponse,
|
||||
): BlockchainProvidersResponse {
|
||||
/*
|
||||
* Example:
|
||||
* val remote = mapOf("a" to 1, "b" to 2, "c" to 3)
|
||||
* val local = mapOf("a" to 11, "e" to 4, "f" to 5)
|
||||
*
|
||||
* local + remote // { a = 1, e = 4, f = 5, b = 2, c = 3 }
|
||||
*/
|
||||
val result = local + remote.filterValues { it.isNotEmpty() }
|
||||
|
||||
if (result != remote) {
|
||||
val missingBlockchains = result.keys - remote.keys
|
||||
val blockchainsWithoutProviders = remote.filterValues { it.isEmpty() }.keys
|
||||
|
||||
recordException(missingBlockchains = missingBlockchains + blockchainsWithoutProviders)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private fun recordException(missingBlockchains: Set<String>) {
|
||||
val exception = IllegalStateException(
|
||||
"Remote config does not contain required blockchains or providers information: " +
|
||||
missingBlockchains.joinToString(),
|
||||
)
|
||||
|
||||
Timber.e(exception)
|
||||
|
||||
firebaseCrashlytics.recordException(exception)
|
||||
}
|
||||
|
||||
private companion object {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue