Updated on 2026-08-14

This commit is contained in:
Tangem 2024-10-23 20:01:15 +03:00
commit cab30e9431
186 changed files with 3729 additions and 2030 deletions

View file

@ -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,
),
)
}
}

View file

@ -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 {

View file

@ -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

View file

@ -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)
}
}
}

View file

@ -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>)
}