Updated on 2026-08-14
This commit is contained in:
commit
652159dbce
316 changed files with 6242 additions and 3084 deletions
|
|
@ -0,0 +1,178 @@
|
|||
package com.tangem.datasource.api.onramp
|
||||
|
||||
import com.tangem.datasource.api.common.response.ApiResponse
|
||||
import com.tangem.datasource.api.onramp.models.common.OnrampDestinationDTO
|
||||
import com.tangem.datasource.api.onramp.models.request.OnrampPairsRequest
|
||||
import com.tangem.datasource.api.onramp.models.response.OnrampDataResponse
|
||||
import com.tangem.datasource.api.onramp.models.response.OnrampQuoteResponse
|
||||
import com.tangem.datasource.api.onramp.models.response.OnrampStatusResponse
|
||||
import com.tangem.datasource.api.onramp.models.response.model.OnrampCountryDTO
|
||||
import com.tangem.datasource.api.onramp.models.response.model.OnrampCurrencyDTO
|
||||
import com.tangem.datasource.api.onramp.models.response.model.OnrampPairDTO
|
||||
import com.tangem.datasource.api.onramp.models.response.model.PaymentMethodDTO
|
||||
|
||||
internal class MockedOnrampApi : OnrampApi {
|
||||
override suspend fun getCurrencies(): ApiResponse<List<OnrampCurrencyDTO>> = ApiResponse.Success(
|
||||
COUNTRIES.map(OnrampCountryDTO::defaultCurrency),
|
||||
)
|
||||
|
||||
override suspend fun getCountries(): ApiResponse<List<OnrampCountryDTO>> = ApiResponse.Success(COUNTRIES + RUSSIA)
|
||||
|
||||
override suspend fun getCountryByIp(): ApiResponse<OnrampCountryDTO> = ApiResponse.Success(RUSSIA)
|
||||
|
||||
override suspend fun getPaymentMethods(): ApiResponse<List<PaymentMethodDTO>> = ApiResponse.Success(
|
||||
listOf(
|
||||
PaymentMethodDTO(id = "google", name = "Google Play", image = ""),
|
||||
PaymentMethodDTO(id = "apple", name = "Apple Pay", image = ""),
|
||||
PaymentMethodDTO(id = "card", name = "Card", image = ""),
|
||||
),
|
||||
)
|
||||
|
||||
override suspend fun getPairs(body: OnrampPairsRequest): ApiResponse<List<OnrampPairDTO>> = ApiResponse.Success(
|
||||
listOf(
|
||||
OnrampPairDTO(
|
||||
fromCurrencyCode = "USD",
|
||||
to = OnrampDestinationDTO(contractAddress = "0xcontract_address", network = "ethereum"),
|
||||
providers = listOf(),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
override suspend fun getQuote(
|
||||
fromCurrencyCode: String,
|
||||
toContractAddress: String,
|
||||
toNetwork: String,
|
||||
paymentMethod: String,
|
||||
countryCode: String,
|
||||
fromAmount: String,
|
||||
toDecimals: Int,
|
||||
providerId: String,
|
||||
): ApiResponse<OnrampQuoteResponse> {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override suspend fun getData(
|
||||
fromCurrencyCode: String,
|
||||
toContractAddress: String,
|
||||
toNetwork: String,
|
||||
paymentMethod: String,
|
||||
countryCode: String,
|
||||
fromAmount: String,
|
||||
toDecimals: Int,
|
||||
providerId: String,
|
||||
toAddress: String,
|
||||
redirectUrl: String,
|
||||
language: String?,
|
||||
theme: String?,
|
||||
requestId: String,
|
||||
): ApiResponse<OnrampDataResponse> {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override suspend fun getStatus(txId: String): ApiResponse<OnrampStatusResponse> {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
private companion object {
|
||||
private val RUSSIA = OnrampCountryDTO(
|
||||
name = "Russia",
|
||||
code = "RU",
|
||||
image = "https://hatscripts.github.io/circle-flags/flags/ru.svg",
|
||||
alpha3 = "RUS",
|
||||
continent = "",
|
||||
defaultCurrency = OnrampCurrencyDTO(
|
||||
name = "Russian ruble",
|
||||
code = "RUB",
|
||||
image = "https://hatscripts.github.io/circle-flags/flags/ru.svg",
|
||||
precision = 2,
|
||||
),
|
||||
onrampAvailable = false,
|
||||
)
|
||||
private val COUNTRIES = listOf(
|
||||
OnrampCountryDTO(
|
||||
name = "United States of America",
|
||||
code = "USA",
|
||||
image = "https://hatscripts.github.io/circle-flags/flags/us.svg",
|
||||
alpha3 = "USA",
|
||||
continent = "",
|
||||
defaultCurrency = OnrampCurrencyDTO(
|
||||
name = "US Dollar",
|
||||
code = "USD",
|
||||
image = "https://hatscripts.github.io/circle-flags/flags/us.svg",
|
||||
precision = 2,
|
||||
),
|
||||
onrampAvailable = true,
|
||||
),
|
||||
OnrampCountryDTO(
|
||||
name = "Europe Union",
|
||||
code = "EU",
|
||||
image = "https://hatscripts.github.io/circle-flags/flags/eu.svg",
|
||||
alpha3 = "EUR",
|
||||
continent = "",
|
||||
defaultCurrency = OnrampCurrencyDTO(
|
||||
name = "Euro",
|
||||
code = "EUR",
|
||||
image = "https://hatscripts.github.io/circle-flags/flags/eu.svg",
|
||||
precision = 2,
|
||||
),
|
||||
onrampAvailable = true,
|
||||
),
|
||||
OnrampCountryDTO(
|
||||
name = "Great Britain",
|
||||
code = "GB",
|
||||
image = "https://hatscripts.github.io/circle-flags/flags/gb.svg",
|
||||
alpha3 = "GB",
|
||||
continent = "",
|
||||
defaultCurrency = OnrampCurrencyDTO(
|
||||
name = "British Pound Sterling",
|
||||
code = "GBP",
|
||||
image = "https://hatscripts.github.io/circle-flags/flags/gb.svg",
|
||||
precision = 2,
|
||||
),
|
||||
onrampAvailable = true,
|
||||
),
|
||||
OnrampCountryDTO(
|
||||
name = "CANADA",
|
||||
code = "CA",
|
||||
image = "https://hatscripts.github.io/circle-flags/flags/ca.svg",
|
||||
alpha3 = "CA",
|
||||
continent = "",
|
||||
defaultCurrency = OnrampCurrencyDTO(
|
||||
name = "Canadian Dollar",
|
||||
code = "CAD",
|
||||
image = "https://hatscripts.github.io/circle-flags/flags/ca.svg",
|
||||
precision = 2,
|
||||
),
|
||||
onrampAvailable = true,
|
||||
),
|
||||
OnrampCountryDTO(
|
||||
name = "Hon Kong",
|
||||
code = "HK",
|
||||
image = "https://hatscripts.github.io/circle-flags/flags/hk.svg",
|
||||
alpha3 = "HK",
|
||||
continent = "",
|
||||
defaultCurrency = OnrampCurrencyDTO(
|
||||
name = "Hon Kong Dollar",
|
||||
code = "HKD",
|
||||
image = "https://hatscripts.github.io/circle-flags/flags/hk.svg",
|
||||
precision = 2,
|
||||
),
|
||||
onrampAvailable = true,
|
||||
),
|
||||
OnrampCountryDTO(
|
||||
name = "Australia",
|
||||
code = "AU",
|
||||
image = "https://hatscripts.github.io/circle-flags/flags/au.svg",
|
||||
alpha3 = "AU",
|
||||
continent = "",
|
||||
defaultCurrency = OnrampCurrencyDTO(
|
||||
name = "Australian Dollar",
|
||||
code = "AUD",
|
||||
image = "https://hatscripts.github.io/circle-flags/flags/au.svg",
|
||||
precision = 2,
|
||||
),
|
||||
onrampAvailable = true,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,8 @@ package com.tangem.datasource.api.stakekit
|
|||
import com.tangem.datasource.api.common.response.ApiResponse
|
||||
import com.tangem.datasource.api.stakekit.models.request.*
|
||||
import com.tangem.datasource.api.stakekit.models.response.EnabledYieldsResponse
|
||||
import com.tangem.datasource.api.stakekit.models.response.EnterActionResponse
|
||||
import com.tangem.datasource.api.stakekit.models.response.ActionDTO
|
||||
import com.tangem.datasource.api.stakekit.models.response.GetActionsResponse
|
||||
import com.tangem.datasource.api.stakekit.models.response.model.BalanceDTO
|
||||
import com.tangem.datasource.api.stakekit.models.response.model.YieldBalanceWrapperDTO
|
||||
import com.tangem.datasource.api.stakekit.models.response.model.transaction.StakingGasEstimateDTO
|
||||
|
|
@ -35,14 +36,23 @@ interface StakeKitApi {
|
|||
@Body body: YieldBalanceRequestBody,
|
||||
): ApiResponse<List<BalanceDTO>>
|
||||
|
||||
@GET("actions")
|
||||
suspend fun getActions(
|
||||
@Query("walletAddress") walletAddress: String,
|
||||
@Query("network") network: String,
|
||||
@Query("status") status: String,
|
||||
@Query("sort") sort: String = "createdAtDesc",
|
||||
@Query("limit") limit: Int = 50,
|
||||
): ApiResponse<GetActionsResponse>
|
||||
|
||||
@POST("actions/enter")
|
||||
suspend fun createEnterAction(@Body body: ActionRequestBody): ApiResponse<EnterActionResponse>
|
||||
suspend fun createEnterAction(@Body body: ActionRequestBody): ApiResponse<ActionDTO>
|
||||
|
||||
@POST("actions/exit")
|
||||
suspend fun createExitAction(@Body body: ActionRequestBody): ApiResponse<EnterActionResponse>
|
||||
suspend fun createExitAction(@Body body: ActionRequestBody): ApiResponse<ActionDTO>
|
||||
|
||||
@POST("actions/pending")
|
||||
suspend fun createPendingAction(@Body body: PendingActionRequestBody): ApiResponse<EnterActionResponse>
|
||||
suspend fun createPendingAction(@Body body: PendingActionRequestBody): ApiResponse<ActionDTO>
|
||||
|
||||
@POST("actions/enter/estimate-gas")
|
||||
suspend fun estimateGasOnEnter(@Body body: ActionRequestBody): ApiResponse<StakingGasEstimateDTO>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import org.joda.time.DateTime
|
|||
import java.math.BigDecimal
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class EnterActionResponse(
|
||||
data class ActionDTO(
|
||||
@Json(name = "id")
|
||||
val id: String,
|
||||
@Json(name = "integrationId")
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package com.tangem.datasource.api.stakekit.models.response
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class GetActionsResponse(
|
||||
@Json(name = "data")
|
||||
val data: List<ActionDTO>,
|
||||
@Json(name = "hasNextPage")
|
||||
val hasNextPage: Boolean,
|
||||
@Json(name = "limit")
|
||||
val limit: Int,
|
||||
@Json(name = "page")
|
||||
val page: Int,
|
||||
)
|
||||
|
|
@ -9,31 +9,31 @@ data class YieldDTO(
|
|||
@Json(name = "id")
|
||||
val id: String,
|
||||
@Json(name = "token")
|
||||
val token: TokenDTO,
|
||||
val token: TokenDTO?,
|
||||
@Json(name = "tokens")
|
||||
val tokens: List<TokenDTO>,
|
||||
val tokens: List<TokenDTO>?,
|
||||
@Json(name = "args")
|
||||
val args: ArgsDTO,
|
||||
val args: ArgsDTO?,
|
||||
@Json(name = "status")
|
||||
val status: StatusDTO,
|
||||
val status: StatusDTO?,
|
||||
@Json(name = "apy")
|
||||
val apy: BigDecimal,
|
||||
val apy: BigDecimal?,
|
||||
@Json(name = "rewardRate")
|
||||
val rewardRate: Double,
|
||||
val rewardRate: Double?,
|
||||
@Json(name = "rewardType")
|
||||
val rewardType: RewardTypeDTO,
|
||||
val rewardType: RewardTypeDTO?,
|
||||
@Json(name = "metadata")
|
||||
val metadata: MetadataDTO,
|
||||
val metadata: MetadataDTO?,
|
||||
@Json(name = "validators")
|
||||
val validators: List<ValidatorDTO>,
|
||||
val validators: List<ValidatorDTO>?,
|
||||
@Json(name = "isAvailable")
|
||||
val isAvailable: Boolean,
|
||||
val isAvailable: Boolean?,
|
||||
) {
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class StatusDTO(
|
||||
@Json(name = "enter")
|
||||
val enter: Boolean,
|
||||
val enter: Boolean?,
|
||||
@Json(name = "exit")
|
||||
val exit: Boolean?,
|
||||
)
|
||||
|
|
@ -41,21 +41,21 @@ data class YieldDTO(
|
|||
@JsonClass(generateAdapter = true)
|
||||
data class ArgsDTO(
|
||||
@Json(name = "enter")
|
||||
val enter: Enter,
|
||||
val enter: Enter?,
|
||||
@Json(name = "exit")
|
||||
val exit: Enter?,
|
||||
) {
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Enter(
|
||||
@Json(name = "addresses")
|
||||
val addresses: Addresses,
|
||||
val addresses: Addresses?,
|
||||
@Json(name = "args")
|
||||
val args: Map<String, AddressArgumentDTO>,
|
||||
val args: Map<String, AddressArgumentDTO>?,
|
||||
) {
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Addresses(
|
||||
@Json(name = "address")
|
||||
val address: AddressArgumentDTO,
|
||||
val address: AddressArgumentDTO?,
|
||||
@Json(name = "additionalAddresses")
|
||||
val additionalAddresses: Map<String, AddressArgumentDTO>? = null,
|
||||
)
|
||||
|
|
@ -65,7 +65,7 @@ data class YieldDTO(
|
|||
@JsonClass(generateAdapter = true)
|
||||
data class ValidatorDTO(
|
||||
@Json(name = "address")
|
||||
val address: String,
|
||||
val address: String?,
|
||||
@Json(name = "status")
|
||||
val status: ValidatorStatusDTO,
|
||||
@Json(name = "name")
|
||||
|
|
@ -106,51 +106,51 @@ data class YieldDTO(
|
|||
@JsonClass(generateAdapter = true)
|
||||
data class MetadataDTO(
|
||||
@Json(name = "name")
|
||||
val name: String,
|
||||
val name: String?,
|
||||
@Json(name = "logoURI")
|
||||
val logoUri: String,
|
||||
val logoUri: String?,
|
||||
@Json(name = "description")
|
||||
val description: String,
|
||||
val description: String?,
|
||||
@Json(name = "documentation")
|
||||
val documentation: String?,
|
||||
@Json(name = "gasFeeToken")
|
||||
val gasFeeTokenDTO: TokenDTO,
|
||||
val gasFeeTokenDTO: TokenDTO?,
|
||||
@Json(name = "token")
|
||||
val tokenDTO: TokenDTO,
|
||||
val tokenDTO: TokenDTO?,
|
||||
@Json(name = "tokens")
|
||||
val tokensDTO: List<TokenDTO>,
|
||||
val tokensDTO: List<TokenDTO>?,
|
||||
@Json(name = "type")
|
||||
val type: String,
|
||||
val type: String?,
|
||||
@Json(name = "rewardSchedule")
|
||||
val rewardSchedule: RewardScheduleDTO,
|
||||
val rewardSchedule: RewardScheduleDTO?,
|
||||
@Json(name = "cooldownPeriod")
|
||||
val cooldownPeriod: PeriodDTO?,
|
||||
@Json(name = "warmupPeriod")
|
||||
val warmupPeriod: PeriodDTO,
|
||||
val warmupPeriod: PeriodDTO?,
|
||||
@Json(name = "rewardClaiming")
|
||||
val rewardClaiming: RewardClaimingDTO,
|
||||
val rewardClaiming: RewardClaimingDTO?,
|
||||
@Json(name = "defaultValidator")
|
||||
val defaultValidator: String?,
|
||||
@Json(name = "minimumStake")
|
||||
val minimumStake: Int?,
|
||||
@Json(name = "supportsMultipleValidators")
|
||||
val supportsMultipleValidators: Boolean,
|
||||
val supportsMultipleValidators: Boolean?,
|
||||
@Json(name = "revshare")
|
||||
val revshare: EnabledDTO,
|
||||
val revshare: EnabledDTO?,
|
||||
@Json(name = "fee")
|
||||
val fee: EnabledDTO,
|
||||
val fee: EnabledDTO?,
|
||||
) {
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class PeriodDTO(
|
||||
@Json(name = "days")
|
||||
val days: Int,
|
||||
val days: Int?,
|
||||
)
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class EnabledDTO(
|
||||
@Json(name = "enabled")
|
||||
val enabled: Boolean,
|
||||
val enabled: Boolean?,
|
||||
)
|
||||
|
||||
enum class RewardScheduleDTO {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import com.tangem.datasource.api.common.config.managers.ProdApiConfigsManager
|
|||
import com.tangem.datasource.api.common.response.ApiResponseCallAdapterFactory
|
||||
import com.tangem.datasource.api.express.TangemExpressApi
|
||||
import com.tangem.datasource.api.markets.TangemTechMarketsApi
|
||||
import com.tangem.datasource.api.onramp.MockedOnrampApi
|
||||
import com.tangem.datasource.api.onramp.OnrampApi
|
||||
import com.tangem.datasource.api.stakekit.StakeKitApi
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||
|
|
@ -98,22 +99,24 @@ internal object NetworkModule {
|
|||
@Provides
|
||||
@Singleton
|
||||
fun provideOnrampApi(
|
||||
@NetworkMoshi moshi: Moshi,
|
||||
@ApplicationContext context: Context,
|
||||
apiConfigsManager: ApiConfigsManager,
|
||||
appLogsStore: AppLogsStore,
|
||||
// @NetworkMoshi moshi: Moshi,
|
||||
// @ApplicationContext context: Context,
|
||||
// apiConfigsManager: ApiConfigsManager,
|
||||
// appLogsStore: AppLogsStore,
|
||||
): OnrampApi {
|
||||
return createApi(
|
||||
id = ApiConfig.ID.Express,
|
||||
moshi = moshi,
|
||||
context = context,
|
||||
apiConfigsManager = apiConfigsManager,
|
||||
clientBuilder = {
|
||||
addInterceptor(
|
||||
NetworkLogsSaveInterceptor(appLogsStore),
|
||||
)
|
||||
},
|
||||
)
|
||||
// TODO: Remove when backend will be ready - [REDACTED_TASK_KEY]
|
||||
return MockedOnrampApi()
|
||||
// return createApi(
|
||||
// id = ApiConfig.ID.Express,
|
||||
// moshi = moshi,
|
||||
// context = context,
|
||||
// apiConfigsManager = apiConfigsManager,
|
||||
// clientBuilder = {
|
||||
// addInterceptor(
|
||||
// NetworkLogsSaveInterceptor(appLogsStore),
|
||||
// )
|
||||
// },
|
||||
// )
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
package com.tangem.datasource.di
|
||||
|
||||
import com.tangem.datasource.local.datastore.RuntimeDataStore
|
||||
import com.tangem.datasource.local.token.*
|
||||
import com.tangem.datasource.local.token.DefaultStakingBalanceStore
|
||||
import com.tangem.datasource.local.token.StakingBalanceStore
|
||||
import com.tangem.datasource.local.token.DefaultStakingYieldsStore
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
|
|
@ -11,11 +12,23 @@ import javax.inject.Singleton
|
|||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
internal object StakingBalanceStoreModule {
|
||||
internal object StakingStoreModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideStakingTokensStore(): StakingYieldsStore {
|
||||
return DefaultStakingYieldsStore()
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideStakingBalanceStore(): StakingBalanceStore {
|
||||
return DefaultStakingBalanceStore(dataStore = RuntimeDataStore())
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideStakingActionsStore(): StakingActionsStore {
|
||||
return DefaultStakingActionsStore(dataStore = RuntimeDataStore())
|
||||
}
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
package com.tangem.datasource.di
|
||||
|
||||
import com.tangem.datasource.local.token.DefaultStakingYieldsStore
|
||||
import com.tangem.datasource.local.token.StakingYieldsStore
|
||||
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 StakingTokensStoreModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideStakingTokensStore(): StakingYieldsStore {
|
||||
return DefaultStakingYieldsStore()
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,8 @@ import com.tangem.datasource.asset.loader.AssetLoader
|
|||
import com.tangem.datasource.local.config.environment.DefaultEnvironmentConfigStorage
|
||||
import com.tangem.datasource.local.config.environment.EnvironmentConfig
|
||||
import com.tangem.datasource.local.config.environment.EnvironmentConfigStorage
|
||||
import com.tangem.datasource.local.config.issuers.DefaultIssuersConfigStorage
|
||||
import com.tangem.datasource.local.config.issuers.IssuersConfigStorage
|
||||
import com.tangem.datasource.local.config.providers.BlockchainProvidersStorage
|
||||
import com.tangem.datasource.local.config.providers.DefaultBlockchainProvidersStorage
|
||||
import com.tangem.datasource.local.config.testnet.DefaultTestnetTokensStorage
|
||||
|
|
@ -30,7 +32,7 @@ internal object ConfigModule {
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun providesTestnetTokensStorage(assetLoader: AssetLoader): TestnetTokensStorage {
|
||||
fun provideTestnetTokensStorage(assetLoader: AssetLoader): TestnetTokensStorage {
|
||||
return DefaultTestnetTokensStorage(assetLoader)
|
||||
}
|
||||
|
||||
|
|
@ -42,4 +44,13 @@ internal object ConfigModule {
|
|||
runtimeStateStore = RuntimeStateStore(defaultValue = emptyMap()),
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideIssuersConfigStorage(assetLoader: AssetLoader): IssuersConfigStorage {
|
||||
return DefaultIssuersConfigStorage(
|
||||
assetLoader = assetLoader,
|
||||
runtimeStateStore = RuntimeStateStore(defaultValue = emptyList()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package com.tangem.datasource.local.config.issuers
|
||||
|
||||
import com.tangem.datasource.asset.loader.AssetLoader
|
||||
import com.tangem.datasource.local.config.issuers.models.Issuer
|
||||
import com.tangem.datasource.local.datastore.RuntimeStateStore
|
||||
|
||||
internal class DefaultIssuersConfigStorage(
|
||||
private val assetLoader: AssetLoader,
|
||||
private val runtimeStateStore: RuntimeStateStore<List<Issuer>>,
|
||||
) : IssuersConfigStorage {
|
||||
|
||||
override suspend fun getConfig(): List<Issuer> {
|
||||
val cachedData = runtimeStateStore.get().value
|
||||
|
||||
if (cachedData.isNotEmpty()) return cachedData
|
||||
|
||||
val issuers = assetLoader.loadList<Issuer>(fileName = ISSUERS_FILE_NAME)
|
||||
|
||||
runtimeStateStore.store(value = issuers)
|
||||
|
||||
return issuers
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val ISSUERS_FILE_NAME = "tangem-app-config/issuers"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package com.tangem.datasource.local.config.issuers
|
||||
|
||||
import com.tangem.datasource.local.config.issuers.models.Issuer
|
||||
|
||||
/**
|
||||
* Storage for list of Twins [Issuer]
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
interface IssuersConfigStorage {
|
||||
|
||||
/** Get config */
|
||||
suspend fun getConfig(): List<Issuer>
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package com.tangem.datasource.local.config.issuers.models
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Issuer(
|
||||
@Json(name = "privateKey") val privateKey: String,
|
||||
@Json(name = "publicKey") val publicKey: String,
|
||||
)
|
||||
|
|
@ -5,6 +5,7 @@ import com.tangem.datasource.local.datastore.core.StringKeyDataStoreDecorator
|
|||
import com.tangem.domain.tokens.model.NetworkStatus
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.utils.extensions.addOrReplace
|
||||
import com.tangem.utils.extensions.replaceBy
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
|
||||
|
|
@ -27,4 +28,23 @@ internal class DefaultNetworksStatusesStore(
|
|||
store(key, newValues)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun storeAll(key: UserWalletId, values: Collection<NetworkStatus>) {
|
||||
mutex.withLock {
|
||||
val currentValues = getSyncOrNull(key) ?: emptySet()
|
||||
val updatedValues = currentValues.toMutableSet()
|
||||
|
||||
values.forEach { newValue ->
|
||||
val isReplaced = updatedValues.replaceBy(newValue) {
|
||||
it.network == newValue.network
|
||||
}
|
||||
|
||||
if (!isReplaced) {
|
||||
updatedValues.add(newValue)
|
||||
}
|
||||
}
|
||||
|
||||
store(key, updatedValues)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -11,4 +11,6 @@ interface NetworksStatusesStore {
|
|||
suspend fun getSyncOrNull(key: UserWalletId): Set<NetworkStatus>?
|
||||
|
||||
suspend fun store(key: UserWalletId, value: NetworkStatus)
|
||||
|
||||
suspend fun storeAll(key: UserWalletId, values: Collection<NetworkStatus>)
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package com.tangem.datasource.local.token
|
||||
|
||||
import com.tangem.datasource.local.datastore.core.StringKeyDataStore
|
||||
import com.tangem.domain.staking.model.stakekit.action.StakingAction
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
|
||||
internal class DefaultStakingActionsStore(
|
||||
private val dataStore: StringKeyDataStore<List<StakingAction>>,
|
||||
) : StakingActionsStore {
|
||||
|
||||
private val mutex = Mutex()
|
||||
|
||||
override fun get(userWalletId: UserWalletId, cryptoCurrencyId: CryptoCurrency.ID): Flow<List<StakingAction>> {
|
||||
return dataStore.get(composeKey(userWalletId, cryptoCurrencyId))
|
||||
}
|
||||
|
||||
override suspend fun store(
|
||||
userWalletId: UserWalletId,
|
||||
cryptoCurrencyId: CryptoCurrency.ID,
|
||||
items: List<StakingAction>,
|
||||
) {
|
||||
mutex.withLock {
|
||||
dataStore.store(composeKey(userWalletId, cryptoCurrencyId), items)
|
||||
}
|
||||
}
|
||||
|
||||
private fun composeKey(userWalletId: UserWalletId, cryptoCurrencyId: CryptoCurrency.ID): String {
|
||||
return userWalletId.stringValue + cryptoCurrencyId.value
|
||||
}
|
||||
}
|
||||
|
|
@ -4,13 +4,13 @@ import com.tangem.datasource.api.stakekit.models.response.model.YieldDTO
|
|||
|
||||
internal class DefaultStakingYieldsStore : StakingYieldsStore {
|
||||
|
||||
private var yields = mutableListOf<YieldDTO>()
|
||||
private var yields = listOf<YieldDTO>()
|
||||
|
||||
override fun get(): List<YieldDTO> {
|
||||
return yields
|
||||
}
|
||||
|
||||
override fun store(items: List<YieldDTO>) {
|
||||
yields = items.toMutableList()
|
||||
yields = items
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.tangem.datasource.local.token
|
||||
|
||||
import com.tangem.domain.staking.model.stakekit.action.StakingAction
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
interface StakingActionsStore {
|
||||
|
||||
fun get(userWalletId: UserWalletId, cryptoCurrencyId: CryptoCurrency.ID): Flow<List<StakingAction>>
|
||||
|
||||
suspend fun store(userWalletId: UserWalletId, cryptoCurrencyId: CryptoCurrency.ID, items: List<StakingAction>)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue