Updated on 2026-08-14
This commit is contained in:
commit
47dc1c38df
762 changed files with 23960 additions and 10924 deletions
|
|
@ -7,9 +7,7 @@ import com.tangem.datasource.api.common.config.ApiEnvironmentConfig
|
|||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.datasource.local.preferences.PreferencesKeys
|
||||
import com.tangem.datasource.local.preferences.utils.getObjectMap
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import com.tangem.utils.coroutines.AppCoroutineScope
|
||||
import kotlinx.coroutines.flow.*
|
||||
|
||||
/**
|
||||
|
|
@ -22,7 +20,7 @@ import kotlinx.coroutines.flow.*
|
|||
internal class DevApiConfigsManager(
|
||||
private val apiConfigs: ApiConfigs,
|
||||
private val appPreferencesStore: AppPreferencesStore,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
private val appScope: AppCoroutineScope,
|
||||
) : MutableApiConfigsManager() {
|
||||
|
||||
override val configs: StateFlow<Map<ApiConfig, ApiEnvironment>>
|
||||
|
|
@ -51,7 +49,7 @@ internal class DevApiConfigsManager(
|
|||
|
||||
notifyListeners(apiConfigs = apiConfigs, savedEnvironments = savedEnvironments)
|
||||
}
|
||||
.launchIn(CoroutineScope(SupervisorJob() + dispatchers.default))
|
||||
.launchIn(appScope)
|
||||
}
|
||||
|
||||
override fun getEnvironmentConfig(id: ApiConfig.ID): ApiEnvironmentConfig {
|
||||
|
|
|
|||
|
|
@ -4,10 +4,22 @@ import com.tangem.datasource.api.common.config.ApiConfig
|
|||
import com.tangem.datasource.api.common.config.ApiConfigs
|
||||
import com.tangem.datasource.api.common.config.ApiEnvironment
|
||||
import com.tangem.datasource.api.common.config.ApiEnvironmentConfig
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import com.tangem.utils.coroutines.AppCoroutineScope
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlin.Boolean
|
||||
import kotlin.String
|
||||
import kotlin.Unit
|
||||
import kotlin.collections.Map
|
||||
import kotlin.collections.any
|
||||
import kotlin.collections.associateWith
|
||||
import kotlin.collections.component1
|
||||
import kotlin.collections.component2
|
||||
import kotlin.collections.first
|
||||
import kotlin.collections.firstOrNull
|
||||
import kotlin.collections.mapValues
|
||||
import kotlin.collections.plus
|
||||
import kotlin.error
|
||||
import kotlin.to
|
||||
|
||||
/**
|
||||
* Implementation of [ApiConfigsManager] in MOCK environment
|
||||
|
|
@ -18,7 +30,7 @@ import kotlinx.coroutines.flow.*
|
|||
*/
|
||||
internal class MockApiConfigsManager(
|
||||
private val apiConfigs: ApiConfigs,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
private val coroutineScope: AppCoroutineScope,
|
||||
) : MutableApiConfigsManager() {
|
||||
|
||||
override val configs: StateFlow<Map<ApiConfig, ApiEnvironment>>
|
||||
|
|
@ -26,8 +38,6 @@ internal class MockApiConfigsManager(
|
|||
|
||||
override val initializedState: StateFlow<Boolean> = MutableStateFlow(value = true)
|
||||
|
||||
private val coroutineScope = CoroutineScope(SupervisorJob() + dispatchers.default)
|
||||
|
||||
override fun initialize() = Unit
|
||||
|
||||
override fun getEnvironmentConfig(id: ApiConfig.ID): ApiEnvironmentConfig {
|
||||
|
|
|
|||
|
|
@ -41,7 +41,8 @@ interface TangemExpressApi {
|
|||
@Query("fromNetwork") fromNetwork: String,
|
||||
@Query("toContractAddress") toContractAddress: String,
|
||||
@Query("toNetwork") toNetwork: String,
|
||||
@Query("fromAmount") fromAmount: String,
|
||||
@Query("fromAmount") fromAmount: String?,
|
||||
@Query("toAmount") toAmount: String? = null,
|
||||
@Query("fromDecimals") fromDecimals: Int,
|
||||
@Query("toDecimals") toDecimals: Int,
|
||||
@Query("providerId") providerId: String,
|
||||
|
|
@ -57,7 +58,8 @@ interface TangemExpressApi {
|
|||
@Query("toContractAddress") toContractAddress: String,
|
||||
@Query("fromAddress") fromAddress: String,
|
||||
@Query("toNetwork") toNetwork: String,
|
||||
@Query("fromAmount") fromAmount: String,
|
||||
@Query("fromAmount") fromAmount: String?,
|
||||
@Query("toAmount") toAmount: String? = null,
|
||||
@Query("fromDecimals") fromDecimals: Int,
|
||||
@Query("toDecimals") toDecimals: Int,
|
||||
@Query("providerId") providerId: String,
|
||||
|
|
|
|||
|
|
@ -37,8 +37,8 @@ interface TangemPayApi {
|
|||
@POST("v1/deeplink/validate")
|
||||
suspend fun validateDeeplink(@Body body: DeeplinkValidityRequest): ApiResponse<DeeplinkValidityResponse>
|
||||
|
||||
@GET("v1/customer/eligibility")
|
||||
suspend fun checkCustomerEligibility(): ApiResponse<CustomerEligibilityResponse>
|
||||
@GET("v1/eligibility/channels")
|
||||
suspend fun getEligibilityChannels(): ApiResponse<TangemPayEligibilityChannels>
|
||||
|
||||
@GET("v1/order/{order_id}")
|
||||
suspend fun getOrder(
|
||||
|
|
|
|||
|
|
@ -4,11 +4,11 @@ import com.squareup.moshi.Json
|
|||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class CustomerEligibilityResponse(
|
||||
@Json(name = "result") val result: Result?,
|
||||
data class TangemPayEligibilityChannels(
|
||||
@Json(name = "result") val result: Result,
|
||||
) {
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Result(
|
||||
@Json(name = "is_tangem_pay_available") val isTangemPayAvailable: Boolean,
|
||||
@Json(name = "channels") val channels: List<String>,
|
||||
)
|
||||
}
|
||||
|
|
@ -5,6 +5,9 @@ import com.tangem.datasource.api.promotion.models.PromoBannerResponse
|
|||
import com.tangem.datasource.api.promotion.models.PromoBannerV2Response
|
||||
import com.tangem.datasource.api.promotion.models.StoryContentResponse
|
||||
import com.tangem.datasource.api.tangemTech.models.*
|
||||
import com.tangem.datasource.api.tangemTech.models.promobanners.PromoBannerDisplaysResponse
|
||||
import com.tangem.datasource.api.tangemTech.models.promobanners.DismissPromoBannerRequest
|
||||
import com.tangem.datasource.api.tangemTech.models.promobanners.DismissPromoBannerResponse
|
||||
import com.tangem.datasource.api.tangemTech.models.account.GetWalletAccountsResponse
|
||||
import com.tangem.datasource.api.tangemTech.models.account.GetWalletArchivedAccountsResponse
|
||||
import com.tangem.datasource.api.tangemTech.models.account.SaveWalletAccountsResponse
|
||||
|
|
@ -25,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,
|
||||
|
|
@ -42,15 +46,6 @@ interface TangemTechApi {
|
|||
@GET("v1/geo")
|
||||
suspend fun getUserCountryCode(): GeoResponse
|
||||
|
||||
@GET("v1/user-tokens/{user-id}")
|
||||
suspend fun getUserTokens(@Path(value = "user-id") userId: String): ApiResponse<UserTokensResponse>
|
||||
|
||||
@PUT("v1/user-tokens/{user-id}")
|
||||
suspend fun saveUserTokens(
|
||||
@Path(value = "user-id") userId: String,
|
||||
@Body userTokens: UserTokensResponse,
|
||||
): ApiResponse<Unit>
|
||||
|
||||
@PUT("/v1/wallets/{walletId}/tokens")
|
||||
suspend fun saveTokens(
|
||||
@Path(value = "walletId") userId: String,
|
||||
|
|
@ -135,14 +130,8 @@ interface TangemTechApi {
|
|||
@PATCH("v1/user-wallets/wallets/{wallet_id}")
|
||||
suspend fun updateWallet(@Path("wallet_id") walletId: String, @Body body: WalletBody): ApiResponse<Unit>
|
||||
|
||||
@POST("v1/user-wallets/wallets/create-and-connect-by-appuid/{application_id}")
|
||||
suspend fun associateApplicationIdWithWallets(
|
||||
@Path("application_id") applicationId: String,
|
||||
@Body body: List<WalletIdBody>,
|
||||
): ApiResponse<Unit>
|
||||
|
||||
@PUT("/v1/user-wallets/applications/{application_id}/wallets")
|
||||
suspend fun associateApplicationIdWithWalletsV2(
|
||||
suspend fun associateApplicationIdWithWallets(
|
||||
@Path("application_id") applicationId: String,
|
||||
@Body body: AssociateApplicationIdWithWalletsBody,
|
||||
): ApiResponse<Unit>
|
||||
|
|
@ -197,6 +186,21 @@ interface TangemTechApi {
|
|||
): ApiResponse<PromoBannerV2Response>
|
||||
// endregion
|
||||
|
||||
// region promo banners
|
||||
@GET("v1/banner/displays")
|
||||
suspend fun getPromoBannerDisplays(
|
||||
@Query("walletId") walletId: String,
|
||||
@Query("placeholder") placeholder: String,
|
||||
@Query("locale") locale: String,
|
||||
): ApiResponse<PromoBannerDisplaysResponse>
|
||||
|
||||
@PATCH("v1/displays/{displayId}")
|
||||
suspend fun dismissPromoBannerDisplay(
|
||||
@Path("displayId") displayId: String,
|
||||
@Body body: DismissPromoBannerRequest,
|
||||
): ApiResponse<DismissPromoBannerResponse>
|
||||
// endregion
|
||||
|
||||
/**
|
||||
* Stores transaction hash in cache to prevent duplicate push
|
||||
* notifications for yield operations (deposit, withdraw, send).
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
package com.tangem.datasource.api.tangemTech.models.promobanners
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class DismissPromoBannerRequest(
|
||||
@Json(name = "walletId") val walletId: String,
|
||||
@Json(name = "isDismissed") val isDismissed: Boolean,
|
||||
)
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package com.tangem.datasource.api.tangemTech.models.promobanners
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class DismissPromoBannerResponse(
|
||||
@Json(name = "displayId") val displayId: String,
|
||||
@Json(name = "walletId") val walletId: String,
|
||||
@Json(name = "isDismissed") val isDismissed: Boolean,
|
||||
@Json(name = "dismissedAt") val dismissedAt: String?,
|
||||
)
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package com.tangem.datasource.api.tangemTech.models.promobanners
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class PromoBannerDisplaysResponse(
|
||||
@Json(name = "items") val items: List<PromoBannerDisplayDTO>,
|
||||
)
|
||||
|
||||
@Suppress("BooleanPropertyNaming")
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class PromoBannerDisplayDTO(
|
||||
@Json(name = "id") val id: String,
|
||||
@Json(name = "placeholder") val placeholder: String,
|
||||
@Json(name = "priority") val priority: String,
|
||||
@Json(name = "title") val title: String,
|
||||
@Json(name = "subtitle") val subtitle: String,
|
||||
@Json(name = "iconUrl") val iconUrl: String?,
|
||||
@Json(name = "deeplink") val deeplink: String?,
|
||||
@Json(name = "buttonEnabled") val buttonEnabled: Boolean,
|
||||
@Json(name = "buttonText") val buttonText: String?,
|
||||
@Json(name = "dismissable") val dismissable: Boolean,
|
||||
)
|
||||
|
|
@ -3,6 +3,7 @@ package com.tangem.datasource.di
|
|||
import android.content.Context
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.tangem.datasource.local.preferences.*
|
||||
import com.tangem.utils.coroutines.AppCoroutineScope
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
|
|
@ -20,10 +21,11 @@ internal object AppPreferencesStoreModule {
|
|||
fun provideAppPreferencesStore(
|
||||
@ApplicationContext appContext: Context,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
appScope: AppCoroutineScope,
|
||||
@SdkMoshi moshi: Moshi,
|
||||
): AppPreferencesStore {
|
||||
return AppPreferencesStore(
|
||||
preferencesDataStore = PreferencesDataStore.getInstance(context = appContext, dispatcher = dispatchers.io),
|
||||
preferencesDataStore = PreferencesDataStore.getInstance(context = appContext, appScope = appScope),
|
||||
moshi = moshi,
|
||||
dispatchers = dispatchers,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -11,14 +11,12 @@ import com.tangem.datasource.local.token.ExpressAssetsStore
|
|||
import com.tangem.datasource.utils.MoshiDataStoreSerializer
|
||||
import com.tangem.datasource.utils.listTypes
|
||||
import com.tangem.datasource.utils.mapWithStringKeyTypes
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.coroutines.AppCoroutineScope
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
|
|
@ -30,7 +28,7 @@ internal object ExpressAssetsStoreModule {
|
|||
fun provideExpressAssetsStore(
|
||||
@NetworkMoshi moshi: Moshi,
|
||||
@ApplicationContext context: Context,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
appScope: AppCoroutineScope,
|
||||
): ExpressAssetsStore {
|
||||
return DefaultExpressAssetsStore(
|
||||
persistenceStore = DataStoreFactory.create(
|
||||
|
|
@ -40,7 +38,7 @@ internal object ExpressAssetsStoreModule {
|
|||
defaultValue = emptyMap(),
|
||||
),
|
||||
produceFile = { context.dataStoreFile("express_assets") },
|
||||
scope = CoroutineScope(context = dispatchers.io + SupervisorJob()),
|
||||
scope = appScope,
|
||||
),
|
||||
runtimeStore = RuntimeDataStore(),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ import com.tangem.datasource.api.visa.VisaApi
|
|||
import com.tangem.datasource.di.utils.RetrofitApiBuilder
|
||||
import com.tangem.datasource.di.utils.RetrofitApiBuilder.Timeouts
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.coroutines.AppCoroutineScope
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
|
|
@ -47,11 +47,11 @@ internal object NetworkModule {
|
|||
fun provideApiConfigManager(
|
||||
apiConfigs: ApiConfigs,
|
||||
appPreferencesStore: AppPreferencesStore,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
appScope: AppCoroutineScope,
|
||||
): ApiConfigsManager {
|
||||
return when {
|
||||
BuildConfig.BUILD_TYPE == MOCKED_BUILD_TYPE -> MockApiConfigsManager(apiConfigs, dispatchers)
|
||||
BuildConfig.TESTER_MENU_ENABLED -> DevApiConfigsManager(apiConfigs, appPreferencesStore, dispatchers)
|
||||
BuildConfig.BUILD_TYPE == MOCKED_BUILD_TYPE -> MockApiConfigsManager(apiConfigs, appScope)
|
||||
BuildConfig.TESTER_MENU_ENABLED -> DevApiConfigsManager(apiConfigs, appPreferencesStore, appScope)
|
||||
else -> ProdApiConfigsManager(apiConfigs)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,14 +20,12 @@ import com.tangem.datasource.utils.MoshiDataStoreSerializer
|
|||
import com.tangem.datasource.utils.listTypes
|
||||
import com.tangem.datasource.utils.mapWithStringKeyTypes
|
||||
import com.tangem.datasource.utils.setTypes
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.coroutines.AppCoroutineScope
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
|
|
@ -39,7 +37,7 @@ internal object StakingStoreModule {
|
|||
fun provideStakingTokensStore(
|
||||
@NetworkMoshi moshi: Moshi,
|
||||
@ApplicationContext context: Context,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
appScope: AppCoroutineScope,
|
||||
): StakingYieldsStore {
|
||||
return DefaultStakingYieldsStore(
|
||||
dataStore = DataStoreFactory.create(
|
||||
|
|
@ -49,7 +47,7 @@ internal object StakingStoreModule {
|
|||
defaultValue = emptyList(),
|
||||
),
|
||||
produceFile = { context.dataStoreFile(fileName = "yields_cache") },
|
||||
scope = CoroutineScope(context = dispatchers.io + SupervisorJob()),
|
||||
scope = appScope,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -59,7 +57,7 @@ internal object StakingStoreModule {
|
|||
fun provideYieldsBalancesPersistenceStore(
|
||||
@NetworkMoshi moshi: Moshi,
|
||||
@ApplicationContext context: Context,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
appScope: AppCoroutineScope,
|
||||
): DataStore<Map<String, Set<YieldBalanceWrapperDTO>>> {
|
||||
return DataStoreFactory.create(
|
||||
serializer = MoshiDataStoreSerializer(
|
||||
|
|
@ -68,7 +66,7 @@ internal object StakingStoreModule {
|
|||
defaultValue = emptyMap(),
|
||||
),
|
||||
produceFile = { context.dataStoreFile(fileName = "yield_balances") },
|
||||
scope = CoroutineScope(context = dispatchers.io + SupervisorJob()),
|
||||
scope = appScope,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -83,7 +81,7 @@ internal object StakingStoreModule {
|
|||
fun provideP2PEthPoolBalancesPersistenceStore(
|
||||
@NetworkMoshi moshi: Moshi,
|
||||
@ApplicationContext context: Context,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
appScope: AppCoroutineScope,
|
||||
): DataStore<Map<String, Set<P2PEthPoolAccountResponse>>> {
|
||||
return DataStoreFactory.create(
|
||||
serializer = MoshiDataStoreSerializer(
|
||||
|
|
@ -92,7 +90,7 @@ internal object StakingStoreModule {
|
|||
defaultValue = emptyMap(),
|
||||
),
|
||||
produceFile = { context.dataStoreFile(fileName = "p2p_eth_pool_balances") },
|
||||
scope = CoroutineScope(context = dispatchers.io + SupervisorJob()),
|
||||
scope = appScope,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -101,7 +99,7 @@ internal object StakingStoreModule {
|
|||
fun provideP2PEthPoolVaultsStore(
|
||||
@NetworkMoshi moshi: Moshi,
|
||||
@ApplicationContext context: Context,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
appScope: AppCoroutineScope,
|
||||
): P2PEthPoolVaultsStore {
|
||||
return DefaultP2PEthPoolVaultsStore(
|
||||
dataStore = DataStoreFactory.create(
|
||||
|
|
@ -111,7 +109,7 @@ internal object StakingStoreModule {
|
|||
defaultValue = emptyList(),
|
||||
),
|
||||
produceFile = { context.dataStoreFile(fileName = "p2p_eth_pool_vaults") },
|
||||
scope = CoroutineScope(context = dispatchers.io + SupervisorJob()),
|
||||
scope = appScope,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,14 +8,12 @@ import com.tangem.datasource.local.token.DefaultTokenReceiveWarningActionStore
|
|||
import com.tangem.datasource.local.token.TokenReceiveWarningActionStore
|
||||
import com.tangem.datasource.utils.MoshiDataStoreSerializer
|
||||
import com.tangem.datasource.utils.setTypes
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.coroutines.AppCoroutineScope
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
|
|
@ -27,7 +25,7 @@ object TokenReceiveWarningModule {
|
|||
fun provideTokenReceiveWarningStore(
|
||||
@NetworkMoshi moshi: Moshi,
|
||||
@ApplicationContext context: Context,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
appScope: AppCoroutineScope,
|
||||
): TokenReceiveWarningActionStore {
|
||||
return DefaultTokenReceiveWarningActionStore(
|
||||
persistenceStore = DataStoreFactory.create(
|
||||
|
|
@ -37,7 +35,7 @@ object TokenReceiveWarningModule {
|
|||
defaultValue = emptySet(),
|
||||
),
|
||||
produceFile = { context.dataStoreFile(fileName = "token_receive_warnings_viewed") },
|
||||
scope = CoroutineScope(context = dispatchers.io + SupervisorJob()),
|
||||
scope = appScope,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,16 +8,14 @@ import com.tangem.datasource.local.walletconnect.DefaultWalletConnectStore
|
|||
import com.tangem.datasource.local.walletconnect.WalletConnectStore
|
||||
import com.tangem.datasource.utils.MoshiDataStoreSerializer
|
||||
import com.tangem.datasource.utils.setTypes
|
||||
import com.tangem.utils.coroutines.AppCoroutineScope
|
||||
import com.tangem.domain.walletconnect.model.WcPendingApprovalSessionDTO
|
||||
import com.tangem.domain.walletconnect.model.WcSessionDTO
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
|
|
@ -29,9 +27,8 @@ object WalletConnectModule {
|
|||
fun provideWalletConnectStore(
|
||||
@NetworkMoshi moshi: Moshi,
|
||||
@ApplicationContext context: Context,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
scope: AppCoroutineScope,
|
||||
): WalletConnectStore {
|
||||
val scope = CoroutineScope(context = dispatchers.io + SupervisorJob())
|
||||
return DefaultWalletConnectStore(
|
||||
persistenceStore = DataStoreFactory.create(
|
||||
serializer = MoshiDataStoreSerializer(
|
||||
|
|
|
|||
|
|
@ -9,14 +9,12 @@ import com.tangem.datasource.local.yieldsupply.DefaultYieldMarketsStore
|
|||
import com.tangem.datasource.local.yieldsupply.YieldMarketsStore
|
||||
import com.tangem.datasource.utils.MoshiDataStoreSerializer
|
||||
import com.tangem.datasource.utils.listTypes
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.coroutines.AppCoroutineScope
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
|
|
@ -28,7 +26,7 @@ object YieldSupplyModule {
|
|||
fun provideYieldMarketsStore(
|
||||
@NetworkMoshi moshi: Moshi,
|
||||
@ApplicationContext context: Context,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
appScope: AppCoroutineScope,
|
||||
): YieldMarketsStore {
|
||||
return DefaultYieldMarketsStore(
|
||||
persistenceStore = DataStoreFactory.create(
|
||||
|
|
@ -38,7 +36,7 @@ object YieldSupplyModule {
|
|||
defaultValue = emptyList(),
|
||||
),
|
||||
produceFile = { context.dataStoreFile(fileName = "yield_markets_cache") },
|
||||
scope = CoroutineScope(context = dispatchers.io + SupervisorJob()),
|
||||
scope = appScope,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,21 +0,0 @@
|
|||
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)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.datasource.local.logs
|
||||
|
||||
import android.content.Context
|
||||
import com.tangem.utils.coroutines.AppCoroutineScope
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.*
|
||||
|
|
@ -27,13 +28,9 @@ import javax.inject.Singleton
|
|||
class AppLogsStore @Inject constructor(
|
||||
@ApplicationContext private val applicationContext: Context,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
private val scope: AppCoroutineScope,
|
||||
) {
|
||||
|
||||
private val scope = CoroutineScope(
|
||||
context = SupervisorJob() + dispatchers.io +
|
||||
CoroutineExceptionHandler { _, error -> Timber.e("AppLogsStore.scope is failed $error") },
|
||||
)
|
||||
|
||||
private val mutex = Mutex()
|
||||
private val zipMutex = Mutex()
|
||||
|
||||
|
|
|
|||
|
|
@ -10,12 +10,10 @@ 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.utils.coroutines.AppCoroutineScope
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.wallet.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
|
||||
|
|
@ -24,7 +22,7 @@ import javax.inject.Singleton
|
|||
class NFTPersistenceStoreFactory @Inject constructor(
|
||||
@NetworkMoshi private val moshi: Moshi,
|
||||
@ApplicationContext private val context: Context,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
private val appScope: AppCoroutineScope,
|
||||
) {
|
||||
|
||||
fun provide(userWalletId: UserWalletId, network: Network): NFTPersistenceStore {
|
||||
|
|
@ -61,7 +59,7 @@ class NFTPersistenceStoreFactory @Inject constructor(
|
|||
defaultValue = defaultValue,
|
||||
),
|
||||
produceFile = { context.dataStoreFile(fileName = fileName) },
|
||||
scope = CoroutineScope(context = dispatchers.io + SupervisorJob()),
|
||||
scope = appScope,
|
||||
)
|
||||
|
||||
private fun Network.ID.formatted(): String = rawId.value
|
||||
|
|
|
|||
|
|
@ -16,10 +16,8 @@ import com.tangem.datasource.local.preferences.PreferencesKeys.IS_WALLET_SWAP_PR
|
|||
import com.tangem.datasource.local.preferences.PreferencesKeys.SHOULD_SHOW_RING_PROMO_KEY
|
||||
import com.tangem.datasource.local.preferences.utils.CleanupKeyMigration
|
||||
import com.tangem.datasource.local.preferences.utils.SharedPreferencesKeyMigration
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import com.tangem.utils.coroutines.AppCoroutineScope
|
||||
import timber.log.Timber
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
/**
|
||||
* Application preferences data store 'DataStore<Preferences>'.
|
||||
|
|
@ -35,15 +33,15 @@ internal object PreferencesDataStore {
|
|||
|
||||
private var INSTANCE: DataStore<Preferences>? = null
|
||||
|
||||
fun getInstance(context: Context, dispatcher: CoroutineContext): DataStore<Preferences> {
|
||||
return INSTANCE ?: create(context, dispatcher).also { INSTANCE = it }
|
||||
fun getInstance(context: Context, appScope: AppCoroutineScope): DataStore<Preferences> {
|
||||
return INSTANCE ?: create(context, appScope).also { INSTANCE = it }
|
||||
}
|
||||
|
||||
private fun create(context: Context, dispatcher: CoroutineContext): DataStore<Preferences> {
|
||||
private fun create(context: Context, appScope: AppCoroutineScope): DataStore<Preferences> {
|
||||
return PreferenceDataStoreFactory.create(
|
||||
corruptionHandler = createCorruptionHandler(),
|
||||
migrations = createMigrations(context = context),
|
||||
scope = CoroutineScope(context = dispatcher + SupervisorJob()),
|
||||
scope = appScope,
|
||||
produceFile = { context.preferencesDataStoreFile(name = PREFERENCES_FILE_NAME) },
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -136,6 +136,8 @@ object PreferencesKeys {
|
|||
|
||||
val HAS_HAD_FIRST_TOP_UP_KEY by lazy { stringPreferencesKey(name = "hasHadFirstTopUp") }
|
||||
|
||||
val PENDING_DISCOVERY_SYNC_KEY by lazy { stringPreferencesKey(name = "pendingDiscoverySync") }
|
||||
|
||||
// region Notifications
|
||||
val NOTIFICATIONS_APPLICATION_ID_KEY by lazy { stringPreferencesKey(name = "notificationsApplicationId") }
|
||||
|
||||
|
|
@ -161,7 +163,7 @@ object PreferencesKeys {
|
|||
val TANGEM_PAY_ACTIVE_WITHDRAW_ORDERS_KEY by lazy {
|
||||
stringPreferencesKey(name = "tangemPayActiveWithdrawOrdersKey")
|
||||
}
|
||||
val TANGEM_PAY_ELIGIBILITY_KEY by lazy { booleanPreferencesKey(name = "tangemPayEligibility") }
|
||||
val TANGEM_PAY_ELIGIBILITY_KEY by lazy { stringSetPreferencesKey(name = "tangemPayEligibilityList") }
|
||||
|
||||
fun getShouldShowNotificationKey(key: String) = booleanPreferencesKey("showShowNotificationUM_$key")
|
||||
// endregion
|
||||
|
|
|
|||
|
|
@ -1,51 +0,0 @@
|
|||
package com.tangem.datasource.local.token
|
||||
|
||||
import androidx.datastore.preferences.core.stringPreferencesKey
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.datasource.local.preferences.utils.getObject
|
||||
import com.tangem.datasource.local.preferences.utils.getObjectSyncOrNull
|
||||
import com.tangem.datasource.local.preferences.utils.storeObject
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
/**
|
||||
* Default implementation of [UserTokensResponseStore]
|
||||
*
|
||||
* @property appPreferencesStore app preferences store
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal class DefaultUserTokensResponseStore(
|
||||
private val appPreferencesStore: AppPreferencesStore,
|
||||
) : UserTokensResponseStore {
|
||||
|
||||
override fun get(userWalletId: UserWalletId): Flow<UserTokensResponse?> {
|
||||
return appPreferencesStore.getObject<UserTokensResponse>(
|
||||
key = createPreferencesKey(userWalletId = userWalletId.stringValue),
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun getSyncOrNull(userWalletId: UserWalletId): UserTokensResponse? {
|
||||
return appPreferencesStore.getObjectSyncOrNull<UserTokensResponse>(
|
||||
key = createPreferencesKey(userWalletId = userWalletId.stringValue),
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun store(userWalletId: UserWalletId, response: UserTokensResponse) {
|
||||
appPreferencesStore.storeObject(
|
||||
key = createPreferencesKey(userWalletId = userWalletId.stringValue),
|
||||
value = response,
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun clear(userWalletId: UserWalletId) {
|
||||
appPreferencesStore.updateData { preferences ->
|
||||
val key = createPreferencesKey(userWalletId = userWalletId.stringValue)
|
||||
|
||||
preferences.toMutablePreferences().apply { remove(key) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun createPreferencesKey(userWalletId: String) = stringPreferencesKey(name = "user_tokens_$userWalletId")
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
package com.tangem.datasource.local.token
|
||||
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
/**
|
||||
* Store of [UserTokensResponse]
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
interface UserTokensResponseStore {
|
||||
|
||||
fun get(userWalletId: UserWalletId): Flow<UserTokensResponse?>
|
||||
|
||||
/** Get [UserTokensResponse] synchronously by [userWalletId] or null */
|
||||
suspend fun getSyncOrNull(userWalletId: UserWalletId): UserTokensResponse?
|
||||
|
||||
suspend fun store(userWalletId: UserWalletId, response: UserTokensResponse)
|
||||
|
||||
suspend fun clear(userWalletId: UserWalletId)
|
||||
}
|
||||
|
|
@ -52,8 +52,8 @@ interface TangemPayStorage {
|
|||
suspend fun getHideMainOnboardingBanner(userWalletId: UserWalletId): Boolean
|
||||
|
||||
suspend fun storeHideOnboardingBanner(userWalletId: UserWalletId, hide: Boolean)
|
||||
suspend fun storeTangemPayEligibility(eligibility: Boolean)
|
||||
suspend fun getTangemPayEligibility(): Boolean
|
||||
suspend fun storeTangemPayEligibility(eligibility: Set<String>)
|
||||
suspend fun getTangemPayEligibility(): Set<String>
|
||||
|
||||
suspend fun clearAll(userWalletId: UserWalletId, customerWalletAddress: String)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue