Updated on 2026-08-14
This commit is contained in:
parent
e0c101f15f
commit
e5e2f4a1e7
13 changed files with 143 additions and 0 deletions
|
|
@ -189,6 +189,7 @@ dependencies {
|
|||
implementation(projects.data.common)
|
||||
implementation(projects.data.settings)
|
||||
implementation(projects.data.tokens)
|
||||
implementation(projects.data.tokensync)
|
||||
implementation(projects.data.txhistory)
|
||||
implementation(projects.data.wallets)
|
||||
implementation(projects.data.analytics)
|
||||
|
|
|
|||
|
|
@ -71,5 +71,9 @@
|
|||
{
|
||||
"name": "VIRTUAL_ACCOUNTS_ENABLED",
|
||||
"version": "undefined"
|
||||
},
|
||||
{
|
||||
"name": "TOKEN_SYNC_ENABLED",
|
||||
"version": "undefined"
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ interface TangemTechApi {
|
|||
suspend fun getCoins(
|
||||
@Header("Cache-Control") cacheControl: String = "max-age=600",
|
||||
@Query("contractAddress") contractAddress: String? = null,
|
||||
@Query("contractAddresses") contractAddresses: String? = null,
|
||||
@Query("exchangeable") exchangeable: Boolean? = null,
|
||||
@Query("networkIds") networkIds: String? = null,
|
||||
@Query("networkId") networkId: String? = null,
|
||||
|
|
|
|||
24
data/tokensync/build.gradle.kts
Normal file
24
data/tokensync/build.gradle.kts
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
plugins {
|
||||
alias(deps.plugins.android.library)
|
||||
alias(deps.plugins.kotlin.android)
|
||||
alias(deps.plugins.kotlin.kapt)
|
||||
alias(deps.plugins.hilt.android)
|
||||
id("configuration")
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "com.tangem.data.tokensync"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(projects.core.datasource)
|
||||
implementation(projects.core.utils)
|
||||
implementation(projects.domain.models)
|
||||
|
||||
implementation(deps.hilt.android)
|
||||
kapt(deps.hilt.kapt)
|
||||
|
||||
implementation(deps.androidx.datastore)
|
||||
implementation(deps.kotlin.coroutines)
|
||||
implementation(deps.moshi)
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package com.tangem.data.tokensync.store
|
||||
|
||||
import androidx.datastore.core.DataStore
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
|
||||
internal class DefaultTokenSyncStore(
|
||||
private val persistenceStore: DataStore<List<UserTokensResponse.Token>>,
|
||||
) : TokenSyncStore {
|
||||
|
||||
override suspend fun get(): List<UserTokensResponse.Token> {
|
||||
return persistenceStore.data.firstOrNull().orEmpty()
|
||||
}
|
||||
|
||||
override suspend fun append(tokens: List<UserTokensResponse.Token>) {
|
||||
persistenceStore.updateData { existing ->
|
||||
(existing + tokens).distinct()
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun clear() {
|
||||
persistenceStore.updateData { emptyList() }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package com.tangem.data.tokensync.store
|
||||
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
|
||||
interface TokenSyncStore {
|
||||
|
||||
suspend fun get(): List<UserTokensResponse.Token>
|
||||
|
||||
suspend fun append(tokens: List<UserTokensResponse.Token>)
|
||||
|
||||
suspend fun clear()
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
package com.tangem.data.tokensync.store
|
||||
|
||||
import android.content.Context
|
||||
import androidx.datastore.core.DataStore
|
||||
import androidx.datastore.core.DataStoreFactory
|
||||
import androidx.datastore.dataStoreFile
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import com.tangem.datasource.di.NetworkMoshi
|
||||
import com.tangem.datasource.utils.MoshiDataStoreSerializer
|
||||
import com.tangem.datasource.utils.listTypes
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.utils.coroutines.AppCoroutineScope
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class TokenSyncStoreFactory @Inject constructor(
|
||||
@NetworkMoshi private val moshi: Moshi,
|
||||
@ApplicationContext private val context: Context,
|
||||
private val appScope: AppCoroutineScope,
|
||||
) {
|
||||
|
||||
private val stores = ConcurrentHashMap<String, TokenSyncStore>()
|
||||
|
||||
fun provide(userWalletId: UserWalletId): TokenSyncStore {
|
||||
val userWalletStringId = userWalletId.formatted()
|
||||
return stores.computeIfAbsent(userWalletStringId) {
|
||||
DefaultTokenSyncStore(
|
||||
persistenceStore = createPersistenceStore(
|
||||
fileName = "token_sync_$userWalletStringId",
|
||||
types = listTypes<UserTokensResponse.Token>(),
|
||||
defaultValue = emptyList(),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <T> createPersistenceStore(
|
||||
fileName: String,
|
||||
types: java.lang.reflect.ParameterizedType,
|
||||
defaultValue: T,
|
||||
): DataStore<T> = DataStoreFactory.create(
|
||||
serializer = MoshiDataStoreSerializer(
|
||||
moshi = moshi,
|
||||
types = types,
|
||||
defaultValue = defaultValue,
|
||||
),
|
||||
produceFile = { context.dataStoreFile(fileName = fileName) },
|
||||
scope = appScope,
|
||||
)
|
||||
|
||||
private fun UserWalletId.formatted(): String = stringValue.lowercase()
|
||||
}
|
||||
|
|
@ -18,6 +18,7 @@ import com.tangem.blockchain.extensions.Result
|
|||
import com.tangem.blockchain.extensions.SimpleResult
|
||||
import com.tangem.blockchain.nft.models.NFTAsset
|
||||
import com.tangem.blockchain.nft.models.NFTCollection
|
||||
import com.tangem.blockchain.tokenbalance.models.TokenBalance
|
||||
import com.tangem.blockchain.transactionhistory.models.TransactionHistoryRequest
|
||||
import com.tangem.blockchain.yieldsupply.YieldSupplyContractCallDataProviderFactory
|
||||
import com.tangem.blockchainsdk.BlockchainSDKFactory
|
||||
|
|
@ -769,6 +770,17 @@ internal class DefaultWalletManagersFacade @Inject constructor(
|
|||
return blockchain.getNFTExploreUrl(assetIdentifier)
|
||||
}
|
||||
|
||||
override suspend fun getTokenBalances(userWalletId: UserWalletId, network: Network): List<TokenBalance> {
|
||||
val blockchain = network.toBlockchain()
|
||||
val walletManager = getOrCreateWalletManager(
|
||||
userWalletId = userWalletId,
|
||||
blockchain = blockchain,
|
||||
derivationPath = network.derivationPath.value,
|
||||
) ?: return emptyList()
|
||||
val address = walletManager.wallet.address
|
||||
return walletManager.getTokenBalances(address)
|
||||
}
|
||||
|
||||
override suspend fun isAccountInitialized(userWalletId: UserWalletId, network: Network): Boolean {
|
||||
val walletManager = getOrCreateWalletManager(userWalletId = userWalletId, network = network)
|
||||
val initializableAccountWalletManger = walletManager as? InitializableAccount ?: return true
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import com.tangem.blockchain.extensions.Result
|
|||
import com.tangem.blockchain.extensions.SimpleResult
|
||||
import com.tangem.blockchain.nft.models.NFTAsset
|
||||
import com.tangem.blockchain.nft.models.NFTCollection
|
||||
import com.tangem.blockchain.tokenbalance.models.TokenBalance
|
||||
import com.tangem.blockchainsdk.models.UpdateWalletManagerResult
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.network.Network
|
||||
|
|
@ -281,6 +282,8 @@ interface WalletManagersFacade {
|
|||
|
||||
suspend fun getNFTExploreUrl(network: Network, assetIdentifier: NFTAsset.Identifier): String?
|
||||
|
||||
suspend fun getTokenBalances(userWalletId: UserWalletId, network: Network): List<TokenBalance>
|
||||
|
||||
/**
|
||||
* If wallet manager implements [InitializableAccount] then returns [InitializableAccount.isAccountInitialized]
|
||||
* value. Otherwise always return true
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ internal class PreviewDetailsComponent : DetailsComponent {
|
|||
router = DummyRouter(),
|
||||
hotWalletFeatureToggles = object : HotWalletFeatureToggles {
|
||||
override val isWalletCreationRestrictionEnabled: Boolean = true
|
||||
override val isTokenSyncEnabled: Boolean = true
|
||||
},
|
||||
).buildAll(
|
||||
isWalletConnectAvailable = true,
|
||||
|
|
|
|||
|
|
@ -2,4 +2,5 @@ package com.tangem.features.hotwallet
|
|||
|
||||
interface HotWalletFeatureToggles {
|
||||
val isWalletCreationRestrictionEnabled: Boolean
|
||||
val isTokenSyncEnabled: Boolean
|
||||
}
|
||||
|
|
@ -8,4 +8,7 @@ internal class DefaultHotWalletFeatureToggles(
|
|||
|
||||
override val isWalletCreationRestrictionEnabled: Boolean
|
||||
get() = featureTogglesManager.isFeatureEnabled(name = "HOT_WALLET_CREATION_RESTRICTION_ENABLED")
|
||||
|
||||
override val isTokenSyncEnabled: Boolean
|
||||
get() = featureTogglesManager.isFeatureEnabled(name = "TOKEN_SYNC_ENABLED")
|
||||
}
|
||||
|
|
@ -401,6 +401,7 @@ include(":data:balance-hiding")
|
|||
include(":data:common")
|
||||
include(":data:card")
|
||||
include(":data:tokens")
|
||||
include(":data:tokensync")
|
||||
include(":data:settings")
|
||||
include(":data:txhistory")
|
||||
include(":data:wallets")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue