Updated on 2026-08-14
This commit is contained in:
parent
5de3e403f0
commit
fb2f23c8a9
35 changed files with 674 additions and 191 deletions
|
|
@ -12,7 +12,7 @@ internal class DefaultNFTPersistenceStore(
|
|||
private val pricesPersistenceStore: DataStore<Map<NFTAsset.Identifier, NFTAsset.SalePrice>>,
|
||||
) : NFTPersistenceStore {
|
||||
|
||||
override fun getCollections(): Flow<List<NFTCollection>> = collectionsPersistenceStore.data
|
||||
override fun getCollections(): Flow<List<NFTCollection>?> = collectionsPersistenceStore.data
|
||||
|
||||
override suspend fun getCollectionsSync(): List<NFTCollection>? = collectionsPersistenceStore
|
||||
.data
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import com.tangem.blockchain.nft.models.NFTCollection
|
|||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
interface NFTPersistenceStore {
|
||||
fun getCollections(): Flow<List<NFTCollection>>
|
||||
fun getCollections(): Flow<List<NFTCollection>?>
|
||||
|
||||
suspend fun getCollectionsSync(): List<NFTCollection>?
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.datasource.local.nft
|
||||
|
||||
import android.content.Context
|
||||
import androidx.datastore.core.DataStore
|
||||
import androidx.datastore.core.DataStoreFactory
|
||||
import androidx.datastore.dataStoreFile
|
||||
import com.squareup.moshi.Moshi
|
||||
|
|
@ -11,10 +12,12 @@ import com.tangem.datasource.utils.MoshiDataStoreSerializer
|
|||
import com.tangem.datasource.utils.listTypes
|
||||
import com.tangem.datasource.utils.mapWithCustomKeyTypes
|
||||
import com.tangem.domain.tokens.model.Network
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import java.lang.reflect.ParameterizedType
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
|
|
@ -25,41 +28,51 @@ class NFTPersistenceStoreFactory @Inject constructor(
|
|||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
) {
|
||||
|
||||
fun provide(network: Network): NFTPersistenceStore {
|
||||
val networkStringIdentifier = listOfNotNull(
|
||||
network.id.value,
|
||||
network.derivationPath.value,
|
||||
).joinToString("_") {
|
||||
// remove all non-alphanumeric characters
|
||||
it
|
||||
.toCharArray()
|
||||
.filter(Char::isLetterOrDigit)
|
||||
.joinToString("")
|
||||
.lowercase()
|
||||
}
|
||||
fun provide(userWalletId: UserWalletId, network: Network): NFTPersistenceStore {
|
||||
// simplify network identifier so that is correct for a file name
|
||||
// e.g. eth_m4460000 or theopennetwork_m446070
|
||||
val networkStringId =
|
||||
network.id.formatted() + network.derivationPath.formatted()?.let { "_$it" }.orEmpty()
|
||||
// simplify user wallet id so that is correct for a file name
|
||||
// e.g. 9a1a178f951a7115555568c09ebad8a882f3d96de25429f0017fe570931e208a
|
||||
val userWalletStringId = userWalletId.formatted()
|
||||
return DefaultNFTPersistenceStore(
|
||||
collectionsPersistenceStore = DataStoreFactory.create(
|
||||
serializer = MoshiDataStoreSerializer(
|
||||
moshi = moshi,
|
||||
types = listTypes<NFTCollection>(),
|
||||
defaultValue = emptyList(),
|
||||
),
|
||||
produceFile = {
|
||||
context.dataStoreFile(fileName = "nft_${networkStringIdentifier}_collections")
|
||||
},
|
||||
scope = CoroutineScope(context = dispatchers.io + SupervisorJob()),
|
||||
collectionsPersistenceStore = createPersistenceStore(
|
||||
// result file name example: nft_9a1a178f951a7115555568c09ebad8a882f3d96de25429f0017fe570931e208a_eth_m4460000_collections
|
||||
// result file name example: nft_9a1a178f951a7115555568c09ebad8a882f3d96de25429f0017fe570931e208a_theopennetwork_m446070_collections
|
||||
fileName = "nft_${userWalletStringId}_${networkStringId}_collections",
|
||||
types = listTypes<NFTCollection>(),
|
||||
defaultValue = emptyList(),
|
||||
),
|
||||
pricesPersistenceStore = DataStoreFactory.create(
|
||||
serializer = MoshiDataStoreSerializer(
|
||||
moshi = moshi,
|
||||
types = mapWithCustomKeyTypes<NFTAsset.Identifier, NFTAsset.SalePrice>(),
|
||||
defaultValue = emptyMap(),
|
||||
),
|
||||
produceFile = {
|
||||
context.dataStoreFile(fileName = "nft_${networkStringIdentifier}_prices")
|
||||
},
|
||||
scope = CoroutineScope(context = dispatchers.io + SupervisorJob()),
|
||||
pricesPersistenceStore = createPersistenceStore(
|
||||
// result file name example: nft_9a1a178f951a7115555568c09ebad8a882f3d96de25429f0017fe570931e208a_eth_m4460000_prices
|
||||
// result file name example: nft_9a1a178f951a7115555568c09ebad8a882f3d96de25429f0017fe570931e208a_theopennetwork_m446070_prices
|
||||
fileName = "nft_${userWalletStringId}_${networkStringId}_prices",
|
||||
types = mapWithCustomKeyTypes<NFTAsset.Identifier, NFTAsset.SalePrice>(),
|
||||
defaultValue = emptyMap(),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun <T> createPersistenceStore(fileName: String, types: ParameterizedType, defaultValue: T): DataStore<T> =
|
||||
DataStoreFactory.create(
|
||||
serializer = MoshiDataStoreSerializer(
|
||||
moshi = moshi,
|
||||
types = types,
|
||||
defaultValue = defaultValue,
|
||||
),
|
||||
produceFile = { context.dataStoreFile(fileName = fileName) },
|
||||
scope = CoroutineScope(context = dispatchers.io + SupervisorJob()),
|
||||
)
|
||||
|
||||
private fun Network.ID.formatted(): String = value
|
||||
.filter(Char::isLetterOrDigit)
|
||||
.lowercase()
|
||||
|
||||
private fun Network.DerivationPath.formatted(): String? = value
|
||||
?.filter(Char::isLetterOrDigit)
|
||||
?.lowercase()
|
||||
|
||||
private fun UserWalletId.formatted(): String = stringValue
|
||||
.lowercase()
|
||||
}
|
||||
|
|
@ -7,14 +7,11 @@ import com.tangem.domain.tokens.model.Network
|
|||
import com.tangem.utils.converter.Converter
|
||||
import com.tangem.blockchain.nft.models.NFTAsset as SdkNFTAsset
|
||||
|
||||
class NFTSdkAssetConverter(
|
||||
private val nftSdkAssetIdentifierConverter: NFTSdkAssetIdentifierConverter,
|
||||
private val nftSdkCollectionIdentifierConverter: NFTSdkCollectionIdentifierConverter,
|
||||
) : Converter<Pair<Network, SdkNFTAsset>, NFTAsset> {
|
||||
object NFTSdkAssetConverter : Converter<Pair<Network, SdkNFTAsset>, NFTAsset> {
|
||||
override fun convert(value: Pair<Network, SdkNFTAsset>): NFTAsset {
|
||||
val (network, asset) = value
|
||||
val assetId = nftSdkAssetIdentifierConverter.convert(asset.identifier)
|
||||
val collectionId = nftSdkCollectionIdentifierConverter.convert(asset.collectionIdentifier)
|
||||
val assetId = NFTSdkAssetIdentifierConverter.convert(asset.identifier)
|
||||
val collectionId = NFTSdkCollectionIdentifierConverter.convert(asset.collectionIdentifier)
|
||||
return NFTAsset.Value(
|
||||
id = assetId,
|
||||
collectionId = collectionId,
|
||||
|
|
|
|||
|
|
@ -6,13 +6,10 @@ import com.tangem.domain.tokens.model.Network
|
|||
import com.tangem.utils.converter.Converter
|
||||
import com.tangem.blockchain.nft.models.NFTCollection as SdkNFTCollection
|
||||
|
||||
class NFTSdkCollectionConverter(
|
||||
private val nftSdkCollectionIdentifierConverter: NFTSdkCollectionIdentifierConverter,
|
||||
private val nftSdkAssetConverter: NFTSdkAssetConverter,
|
||||
) : Converter<Pair<Network, SdkNFTCollection>, NFTCollection> {
|
||||
object NFTSdkCollectionConverter : Converter<Pair<Network, SdkNFTCollection>, NFTCollection> {
|
||||
override fun convert(value: Pair<Network, SdkNFTCollection>): NFTCollection {
|
||||
val (network, collection) = value
|
||||
val collectionId = nftSdkCollectionIdentifierConverter.convert(collection.identifier)
|
||||
val collectionId = NFTSdkCollectionIdentifierConverter.convert(collection.identifier)
|
||||
return NFTCollection(
|
||||
id = collectionId,
|
||||
network = network,
|
||||
|
|
@ -22,7 +19,7 @@ class NFTSdkCollectionConverter(
|
|||
count = collection.count,
|
||||
assets = collection.assets
|
||||
.map { asset ->
|
||||
nftSdkAssetConverter.convert(network to asset)
|
||||
NFTSdkAssetConverter.convert(network to asset)
|
||||
}
|
||||
.filter {
|
||||
it.id !is NFTAsset.Identifier.Unknown
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue