Updated on 2026-08-14

This commit is contained in:
Tangem 2025-05-12 18:09:27 +03:00
commit c1cc66fea8
162 changed files with 3408 additions and 1585 deletions

View file

@ -11,4 +11,9 @@ interface AuthProvider {
fun getCardPublicKey(): String
fun getCardId(): String
/**
* Returns map where keys(cardId) associated with cardPublicKey
*/
fun getCardsPublicKeys(): Map<String, String>
}

View file

@ -172,6 +172,9 @@ interface TangemTechApi {
@GET("user-wallets/wallets/{wallet_id}")
suspend fun getWalletById(@Path("wallet_id") walletId: String): ApiResponse<WalletResponse>
@GET("user-wallets/wallets/by-app/{app_id}")
suspend fun getWallets(@Path("app_id") appId: String): ApiResponse<List<WalletResponse>>
// endregion
companion object {

View file

@ -0,0 +1,10 @@
package com.tangem.datasource.api.tangemTech.models
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class CardInfoBody(
@Json(name = "card_id") val cardId: String,
@Json(name = "card_public_key") val cardPublicKey: String,
)

View file

@ -6,4 +6,6 @@ import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class WalletIdBody(
@Json(name = "id") val walletId: String,
@Json(name = "name") val name: String,
@Json(name = "cards") val cards: List<CardInfoBody>,
)

View file

@ -0,0 +1,21 @@
package com.tangem.datasource.di.local
import com.tangem.datasource.local.preferences.AppPreferencesStore
import com.tangem.datasource.local.token.DefaultUserTokensResponseStore
import com.tangem.datasource.local.token.UserTokensResponseStore
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
internal object LocalTokenModule {
@Provides
@Singleton
fun provideUserTokensResponseStore(appPreferencesStore: AppPreferencesStore): UserTokensResponseStore {
return DefaultUserTokensResponseStore(appPreferencesStore = appPreferencesStore)
}
}

View file

@ -3,13 +3,14 @@ package com.tangem.datasource.local.nft
import androidx.datastore.core.DataStore
import com.tangem.blockchain.nft.models.NFTAsset
import com.tangem.blockchain.nft.models.NFTCollection
import com.tangem.datasource.local.nft.custom.NFTPriceId
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.flow.map
internal class DefaultNFTPersistenceStore(
private val collectionsPersistenceStore: DataStore<List<NFTCollection>>,
private val pricesPersistenceStore: DataStore<Map<NFTAsset.Identifier, NFTAsset.SalePrice>>,
private val pricesPersistenceStore: DataStore<List<NFTPriceId>>,
) : NFTPersistenceStore {
override fun getCollections(): Flow<List<NFTCollection>?> = collectionsPersistenceStore.data
@ -27,11 +28,12 @@ internal class DefaultNFTPersistenceStore(
}
override fun getSalePrice(assetId: NFTAsset.Identifier): Flow<NFTAsset.SalePrice?> = pricesPersistenceStore.data
.map { it[assetId] }
.map { data -> data.associate { it.assetId to it.price }[assetId] }
override suspend fun getSalePricesSync(): Map<NFTAsset.Identifier, NFTAsset.SalePrice>? = pricesPersistenceStore
.data
.firstOrNull()
?.associate { it.assetId to it.price }
override suspend fun saveCollections(collections: List<NFTCollection>) {
collectionsPersistenceStore.updateData {
@ -41,7 +43,7 @@ internal class DefaultNFTPersistenceStore(
override suspend fun saveSalePrice(assetId: NFTAsset.Identifier, salePrice: NFTAsset.SalePrice) {
pricesPersistenceStore.updateData {
it.toMutableMap().apply { this[assetId] = salePrice }
it.toMutableList().plus(NFTPriceId(assetId = assetId, price = salePrice))
}
}

View file

@ -5,12 +5,11 @@ import androidx.datastore.core.DataStore
import androidx.datastore.core.DataStoreFactory
import androidx.datastore.dataStoreFile
import com.squareup.moshi.Moshi
import com.tangem.blockchain.nft.models.NFTAsset
import com.tangem.blockchain.nft.models.NFTCollection
import com.tangem.datasource.di.NetworkMoshi
import com.tangem.datasource.local.nft.custom.NFTPriceId
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
@ -48,8 +47,8 @@ class NFTPersistenceStoreFactory @Inject constructor(
// 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(),
types = listTypes<NFTPriceId>(),
defaultValue = emptyList(),
),
)
}

View file

@ -0,0 +1,8 @@
package com.tangem.datasource.local.nft.custom
import com.tangem.blockchain.nft.models.NFTAsset
data class NFTPriceId(
val assetId: NFTAsset.Identifier,
val price: NFTAsset.SalePrice,
)

View file

@ -0,0 +1,25 @@
package com.tangem.datasource.local.token
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
import com.tangem.datasource.local.preferences.AppPreferencesStore
import com.tangem.datasource.local.preferences.PreferencesKeys
import com.tangem.datasource.local.preferences.utils.getObjectSyncOrNull
import com.tangem.domain.wallets.models.UserWalletId
/**
* Default implementation of [UserTokensResponseStore]
*
* @property appPreferencesStore app preferences store
*
[REDACTED_AUTHOR]
*/
internal class DefaultUserTokensResponseStore(
private val appPreferencesStore: AppPreferencesStore,
) : UserTokensResponseStore {
override suspend fun getSyncOrNull(userWalletId: UserWalletId): UserTokensResponse? {
return appPreferencesStore.getObjectSyncOrNull<UserTokensResponse>(
key = PreferencesKeys.getUserTokensKey(userWalletId = userWalletId.stringValue),
)
}
}

View file

@ -0,0 +1,15 @@
package com.tangem.datasource.local.token
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
import com.tangem.domain.wallets.models.UserWalletId
/**
* Store of [UserTokensResponse]
*
[REDACTED_AUTHOR]
*/
interface UserTokensResponseStore {
/** Get [UserTokensResponse] synchronously by [userWalletId] or null */
suspend fun getSyncOrNull(userWalletId: UserWalletId): UserTokensResponse?
}