Updated on 2026-08-14
This commit is contained in:
commit
226a413558
994 changed files with 27178 additions and 11929 deletions
|
|
@ -1,13 +1,43 @@
|
|||
package com.tangem.datasource.api.common.adapter
|
||||
|
||||
import com.squareup.moshi.*
|
||||
import com.squareup.moshi.JsonAdapter
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.squareup.moshi.adapters.EnumJsonAdapter
|
||||
import com.tangem.datasource.api.stakekit.models.response.model.BalanceDTO
|
||||
import com.tangem.datasource.api.stakekit.models.response.model.NetworkTypeDTO
|
||||
import com.tangem.datasource.api.stakekit.models.response.model.YieldDTO
|
||||
import com.tangem.datasource.api.stakekit.models.response.model.action.StakingActionStatusDTO
|
||||
import com.tangem.datasource.api.stakekit.models.response.model.action.StakingActionTypeDTO
|
||||
import com.tangem.datasource.api.stakekit.models.response.model.transaction.StakingTransactionStatusDTO
|
||||
import com.tangem.datasource.api.stakekit.models.response.model.transaction.StakingTransactionTypeDTO
|
||||
|
||||
/**
|
||||
* Object to create a adapter for enum types with support for unknown enum values.
|
||||
*/
|
||||
object UnknownEnumMoshiAdapter {
|
||||
|
||||
fun <T : Enum<T>> create(enumType: Class<T>, defaultValue: T): JsonAdapter<T> =
|
||||
EnumJsonAdapter.create(enumType).withUnknownFallback(defaultValue)
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T : Enum<T>> create(enumType: Class<out Enum<*>>, defaultValue: Enum<*>): JsonAdapter<out Enum<*>> {
|
||||
return EnumJsonAdapter.create(enumType as Class<T>).withUnknownFallback(defaultValue as T)
|
||||
}
|
||||
}
|
||||
|
||||
fun Moshi.Builder.addStakeKitEnumFallbackAdapters(): Moshi.Builder {
|
||||
val map = mapOf(
|
||||
NetworkTypeDTO::class.java to NetworkTypeDTO.UNKNOWN,
|
||||
StakingActionTypeDTO::class.java to StakingActionTypeDTO.UNKNOWN,
|
||||
YieldDTO.RewardTypeDTO::class.java to YieldDTO.RewardTypeDTO.UNKNOWN,
|
||||
BalanceDTO.BalanceType::class.java to BalanceDTO.BalanceType.UNKNOWN,
|
||||
StakingTransactionTypeDTO::class.java to StakingTransactionTypeDTO.UNKNOWN,
|
||||
StakingTransactionStatusDTO::class.java to StakingTransactionStatusDTO.UNKNOWN,
|
||||
StakingActionStatusDTO::class.java to StakingActionStatusDTO.UNKNOWN,
|
||||
)
|
||||
|
||||
return apply {
|
||||
map.forEach { entry ->
|
||||
val enumClass = entry.key
|
||||
val unknownValue = entry.value
|
||||
add(enumClass, UnknownEnumMoshiAdapter.create(enumClass, unknownValue))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
package com.tangem.datasource.api.markets
|
||||
|
||||
import com.tangem.datasource.api.common.response.ApiResponse
|
||||
import com.tangem.datasource.api.markets.models.response.*
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.Path
|
||||
import retrofit2.http.Query
|
||||
|
||||
interface TangemTechMarketsApi {
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
@GET("coins/list")
|
||||
suspend fun getCoinsList(
|
||||
@Query("currency") currency: String,
|
||||
@Query("interval") interval: String,
|
||||
@Query("offset") offset: Int,
|
||||
@Query("limit") limit: Int,
|
||||
@Query("order") order: String,
|
||||
@Query("general_coins") generalCoins: Boolean,
|
||||
@Query("search") search: String?,
|
||||
): ApiResponse<TokenMarketListResponse>
|
||||
|
||||
@GET("coins/{coin_id}")
|
||||
suspend fun getCoinMarketData(
|
||||
@Path("coin_id") coinId: String,
|
||||
@Query("currency") currency: String,
|
||||
): ApiResponse<TokenMarketDetailsResponse>
|
||||
|
||||
@GET("coins/{coin_id}/history")
|
||||
suspend fun getCoinChart(
|
||||
@Query("currency") currency: String,
|
||||
@Query("interval") interval: String,
|
||||
): ApiResponse<TokenMarketChartResponse>
|
||||
|
||||
@GET("coins/history_preview")
|
||||
suspend fun getCoinsListCharts(
|
||||
@Query("coin_ids") coinIds: String,
|
||||
@Query("currency") currency: String,
|
||||
@Query("interval") interval: String,
|
||||
): ApiResponse<TokenMarketChartListResponse>
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
package com.tangem.datasource.api.markets.models.response
|
||||
|
||||
typealias TokenMarketChartListResponse = Map<String, TokenMarketChartResponse>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package com.tangem.datasource.api.markets.models.response
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import java.math.BigDecimal
|
||||
|
||||
data class TokenMarketChartResponse(
|
||||
@Json(name = "prices")
|
||||
val prices: Map<Long, BigDecimal>,
|
||||
)
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
package com.tangem.datasource.api.markets.models.response
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import java.math.BigDecimal
|
||||
|
||||
data class TokenMarketDetailsResponse(
|
||||
@Json(name = "id")
|
||||
val id: String,
|
||||
@Json(name = "name")
|
||||
val name: String,
|
||||
@Json(name = "symbol")
|
||||
val symbol: String,
|
||||
@Json(name = "active")
|
||||
val active: Boolean,
|
||||
@Json(name = "current_price")
|
||||
val currentPrice: BigDecimal,
|
||||
@Json(name = "price_change_percentage")
|
||||
val priceChangePercentage: PriceChangePercentage,
|
||||
@Json(name = "networks")
|
||||
val networks: List<Network>,
|
||||
@Json(name = "short_description")
|
||||
val shortDescription: String?,
|
||||
@Json(name = "full_description")
|
||||
val fullDescription: String?,
|
||||
@Json(name = "insights")
|
||||
val insights: List<Insight>?,
|
||||
@Json(name = "metrics")
|
||||
val metrics: Metrics,
|
||||
@Json(name = "links")
|
||||
val links: Links,
|
||||
@Json(name = "price_performance")
|
||||
val pricePerformance: PricePerformance,
|
||||
) {
|
||||
data class PriceChangePercentage(
|
||||
@Json(name = "24h")
|
||||
val h24: BigDecimal,
|
||||
@Json(name = "1w")
|
||||
val week1: BigDecimal,
|
||||
@Json(name = "1m")
|
||||
val month1: BigDecimal,
|
||||
@Json(name = "3m")
|
||||
val month3: BigDecimal,
|
||||
@Json(name = "6m")
|
||||
val month6: BigDecimal,
|
||||
@Json(name = "1y")
|
||||
val year1: BigDecimal,
|
||||
@Json(name = "all_time")
|
||||
val allTime: BigDecimal,
|
||||
)
|
||||
|
||||
data class Network(
|
||||
@Json(name = "network_id")
|
||||
val networkId: String,
|
||||
@Json(name = "exchangeable")
|
||||
val exchangeable: Boolean,
|
||||
@Json(name = "contract_address")
|
||||
val contractAddress: String,
|
||||
@Json(name = "decimalCount")
|
||||
val decimalCount: Int,
|
||||
)
|
||||
|
||||
data class Insight(
|
||||
@Json(name = "holders_change")
|
||||
val holdersChange: Change,
|
||||
@Json(name = "liquidity_change")
|
||||
val liquidityChange: Change,
|
||||
@Json(name = "buy_pressure_change")
|
||||
val buyPressureChange: Change,
|
||||
@Json(name = "experienced_buyer_change")
|
||||
val experiencedBuyerChange: Change,
|
||||
) {
|
||||
data class Change(
|
||||
@Json(name = "1d")
|
||||
val day1: Int,
|
||||
@Json(name = "1w")
|
||||
val week1: Int,
|
||||
@Json(name = "1m")
|
||||
val month1: Int,
|
||||
)
|
||||
}
|
||||
|
||||
data class Metrics(
|
||||
@Json(name = "market_rating")
|
||||
val marketRating: Int,
|
||||
@Json(name = "circulating_supply")
|
||||
val circulatingSupply: BigDecimal,
|
||||
@Json(name = "market_cap")
|
||||
val marketCap: BigDecimal,
|
||||
@Json(name = "volume_24h")
|
||||
val volume24h: BigDecimal,
|
||||
@Json(name = "total_supply")
|
||||
val totalSupply: BigDecimal,
|
||||
@Json(name = "fully_diluted_valuation")
|
||||
val fullyDilutedValuation: BigDecimal,
|
||||
)
|
||||
|
||||
data class Links(
|
||||
@Json(name = "official_links")
|
||||
val officialLinks: List<Link> = emptyList(),
|
||||
@Json(name = "social")
|
||||
val social: List<Link> = emptyList(),
|
||||
@Json(name = "repository")
|
||||
val repository: List<Link> = emptyList(),
|
||||
@Json(name = "blockchain_site")
|
||||
val blockchainSite: List<Link> = emptyList(),
|
||||
)
|
||||
|
||||
data class Link(
|
||||
@Json(name = "title")
|
||||
val title: String?,
|
||||
@Json(name = "id")
|
||||
val id: String,
|
||||
@Json(name = "link")
|
||||
val url: String,
|
||||
)
|
||||
|
||||
data class PricePerformance(
|
||||
@Json(name = "high_price")
|
||||
val highPrice: Price,
|
||||
@Json(name = "low_price")
|
||||
val lowPrice: Price,
|
||||
) {
|
||||
data class Price(
|
||||
@Json(name = "24h")
|
||||
val h24: BigDecimal,
|
||||
@Json(name = "1m")
|
||||
val month1: BigDecimal,
|
||||
@Json(name = "all_time")
|
||||
val allTime: BigDecimal,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
package com.tangem.datasource.api.markets.models.response
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import java.math.BigDecimal
|
||||
|
||||
data class TokenMarketListResponse(
|
||||
@Json(name = "imageHost")
|
||||
val imageHost: String,
|
||||
@Json(name = "tokens")
|
||||
val tokens: List<Token>,
|
||||
@Json(name = "total")
|
||||
val total: Int,
|
||||
@Json(name = "limit")
|
||||
val limit: Int,
|
||||
@Json(name = "offset")
|
||||
val offset: Int,
|
||||
) {
|
||||
data class Token(
|
||||
@Json(name = "id")
|
||||
val id: String,
|
||||
@Json(name = "name")
|
||||
val name: String,
|
||||
@Json(name = "symbol")
|
||||
val symbol: String,
|
||||
@Json(name = "current_price")
|
||||
val currentPrice: BigDecimal,
|
||||
@Json(name = "price_change_percentage")
|
||||
val priceChangePercentage: PriceChangePercentage,
|
||||
@Json(name = "market_rating")
|
||||
val marketRating: Int?,
|
||||
@Json(name = "market_cap")
|
||||
val marketCap: BigDecimal?,
|
||||
) {
|
||||
data class PriceChangePercentage(
|
||||
@Json(name = "24h")
|
||||
val h24: BigDecimal,
|
||||
@Json(name = "1w")
|
||||
val week1: BigDecimal,
|
||||
@Json(name = "30d")
|
||||
val day30: BigDecimal,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,48 +1,71 @@
|
|||
package com.tangem.datasource.api.stakekit
|
||||
|
||||
import com.tangem.datasource.api.common.response.ApiResponse
|
||||
import com.tangem.datasource.api.stakekit.models.request.YieldBalanceRequestBody
|
||||
import com.tangem.datasource.api.stakekit.models.request.RevenueOption
|
||||
import com.tangem.datasource.api.stakekit.models.request.YieldType
|
||||
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.model.TokenWithYield
|
||||
import com.tangem.datasource.api.stakekit.models.response.model.Yield
|
||||
import com.tangem.datasource.api.stakekit.models.response.model.YieldBalanceWrapper
|
||||
import retrofit2.http.Body
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.Path
|
||||
import retrofit2.http.Query
|
||||
import com.tangem.datasource.api.stakekit.models.response.EnterActionResponse
|
||||
import com.tangem.datasource.api.stakekit.models.response.model.BalanceDTO
|
||||
import com.tangem.datasource.api.stakekit.models.response.model.TokenWithYieldDTO
|
||||
import com.tangem.datasource.api.stakekit.models.response.model.YieldBalanceWrapperDTO
|
||||
import com.tangem.datasource.api.stakekit.models.response.model.YieldDTO
|
||||
import com.tangem.datasource.api.stakekit.models.response.model.transaction.StakingGasEstimateDTO
|
||||
import com.tangem.datasource.api.stakekit.models.response.model.transaction.StakingTransactionDTO
|
||||
import retrofit2.http.*
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
interface StakeKitApi {
|
||||
|
||||
@GET("yields/enabled")
|
||||
suspend fun getMultipleYields(
|
||||
@Query("ledgerWalletAPICompatible") ledgerWalletAPICompatible: Boolean,
|
||||
@Query("type") type: YieldType,
|
||||
@Query("revenueOption") revenueOption: RevenueOption,
|
||||
@Query("page") page: Int,
|
||||
@Query("network") network: String,
|
||||
@Query("limit") limit: Int,
|
||||
@Query("ledgerWalletAPICompatible") ledgerWalletAPICompatible: Boolean? = null,
|
||||
@Query("type") type: YieldType? = null,
|
||||
@Query("revenueOption") revenueOption: RevenueOption? = null,
|
||||
@Query("page") page: Int? = null,
|
||||
@Query("network") network: String? = null,
|
||||
@Query("limit") limit: Int? = null,
|
||||
): ApiResponse<EnabledYieldsResponse>
|
||||
|
||||
@GET("yields/{integrationId}")
|
||||
suspend fun getSingleYield(
|
||||
@Path("integrationId") integrationId: String,
|
||||
@Query("ledgerWalletAPICompatible") ledgerWalletAPICompatible: Boolean = false,
|
||||
): ApiResponse<Yield>
|
||||
): ApiResponse<YieldDTO>
|
||||
|
||||
@GET("yields/balances")
|
||||
@POST("yields/balances")
|
||||
suspend fun getMultipleYieldBalances(
|
||||
@Body body: List<YieldBalanceRequestBody>,
|
||||
): ApiResponse<List<YieldBalanceWrapper>>
|
||||
): ApiResponse<List<YieldBalanceWrapperDTO>>
|
||||
|
||||
@GET("yields/{integrationId}/balances")
|
||||
@POST("yields/{integrationId}/balances")
|
||||
suspend fun getSingleYieldBalance(
|
||||
@Path("integrationId") integrationId: String,
|
||||
@Body body: YieldBalanceRequestBody,
|
||||
): ApiResponse<YieldBalanceWrapper>
|
||||
): ApiResponse<List<BalanceDTO>>
|
||||
|
||||
@GET("tokens")
|
||||
suspend fun getTokens(): ApiResponse<List<TokenWithYield>>
|
||||
suspend fun getTokens(): ApiResponse<List<TokenWithYieldDTO>>
|
||||
|
||||
@POST("actions/enter")
|
||||
suspend fun createEnterAction(@Body body: ActionRequestBody): ApiResponse<EnterActionResponse>
|
||||
|
||||
@POST("actions/exit")
|
||||
suspend fun createExitAction(@Body body: ActionRequestBody): ApiResponse<EnterActionResponse>
|
||||
|
||||
@POST("actions/enter/estimate-gas")
|
||||
suspend fun estimateGasOnEnter(@Body body: ActionRequestBody): ApiResponse<StakingGasEstimateDTO>
|
||||
|
||||
@POST("actions/exit/estimate-gas")
|
||||
suspend fun estimateGasOnExit(@Body body: ActionRequestBody): ApiResponse<StakingGasEstimateDTO>
|
||||
|
||||
@PATCH("transactions/{transactionId}")
|
||||
suspend fun constructTransaction(
|
||||
@Path("transactionId") transactionId: String,
|
||||
@Body body: ConstructTransactionRequestBody,
|
||||
): ApiResponse<StakingTransactionDTO>
|
||||
|
||||
@POST("transactions/{transactionId}/submit_hash")
|
||||
suspend fun submitTransactionHash(
|
||||
@Path("transactionId") transactionId: String,
|
||||
@Body body: SubmitTransactionHashRequestBody,
|
||||
): ApiResponse<Unit>
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
package com.tangem.datasource.api.stakekit.models.request
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.tangem.datasource.api.stakekit.models.request.ConstructTransactionRequestBody.GasArgs
|
||||
import com.tangem.datasource.api.stakekit.models.response.model.BalanceDTO
|
||||
import com.tangem.datasource.api.stakekit.models.response.model.TokenDTO
|
||||
|
||||
data class ActionRequestBody(
|
||||
@Json(name = "integrationId")
|
||||
val integrationId: String,
|
||||
@Json(name = "addresses")
|
||||
val addresses: Address,
|
||||
@Json(name = "args")
|
||||
val args: EnterActionRequestBodyArgs,
|
||||
@Json(name = "referralCode")
|
||||
val referralCode: String? = null,
|
||||
@Json(name = "gasArgs")
|
||||
val gasArgs: GasArgs? = null, // used only in estimate_gas request
|
||||
) {
|
||||
|
||||
data class EnterActionRequestBodyArgs(
|
||||
@Json(name = "amount")
|
||||
val amount: String,
|
||||
@Json(name = "validatorAddress")
|
||||
val validatorAddress: String? = null,
|
||||
@Json(name = "validatorAddresses")
|
||||
val validatorAddresses: List<String>? = null,
|
||||
@Json(name = "providerId")
|
||||
val providerId: String? = null,
|
||||
@Json(name = "duration")
|
||||
val duration: String? = null,
|
||||
@Json(name = "nfts")
|
||||
val nfts: List<BalanceDTO.PendingAction.PendingActionArgs.Nft>? = null,
|
||||
@Json(name = "ledgerWalletAPICompatible")
|
||||
val ledgerWalletAPICompatible: Boolean? = null,
|
||||
@Json(name = "tronResource")
|
||||
val tronResource: String? = null,
|
||||
@Json(name = "signatureVerification")
|
||||
val signatureVerification: SignatureVerification? = null,
|
||||
@Json(name = "inputToken")
|
||||
val inputToken: TokenDTO? = null,
|
||||
)
|
||||
|
||||
data class SignatureVerification(
|
||||
@Json(name = "message")
|
||||
val message: String,
|
||||
@Json(name = "signed")
|
||||
val signed: String,
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
package com.tangem.datasource.api.stakekit.models.request
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
|
||||
data class Address(
|
||||
@Json(name = "address")
|
||||
val address: String,
|
||||
@Json(name = "additionalAddresses")
|
||||
val additionalAddresses: AdditionalAddresses? = null,
|
||||
@Json(name = "explorerUrl")
|
||||
val explorerUrl: String? = null,
|
||||
) {
|
||||
|
||||
data class AdditionalAddresses(
|
||||
// cosmos-specific
|
||||
@Json(name = "cosmosPubKey")
|
||||
val cosmosPubKey: String? = null,
|
||||
|
||||
// binance-specific
|
||||
@Json(name = "binanceBeaconAddress")
|
||||
val binanceBeaconAddress: String? = null,
|
||||
|
||||
// solana-specific
|
||||
@Json(name = "stakeAccounts")
|
||||
val stakeAccounts: List<String>? = null,
|
||||
@Json(name = "lidoStakeAccounts")
|
||||
val lidoStakeAccounts: List<String>? = null,
|
||||
|
||||
// tezos-specific
|
||||
@Json(name = "tezosPubKey")
|
||||
val tezosPubKey: String? = null,
|
||||
|
||||
// avalanche-specific
|
||||
@Json(name = "cAddressBech")
|
||||
val cAddressBech: String? = null,
|
||||
@Json(name = "pAddressBech")
|
||||
val pAddressBech: String? = null,
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package com.tangem.datasource.api.stakekit.models.request
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import java.math.BigDecimal
|
||||
|
||||
data class ConstructTransactionRequestBody(
|
||||
@Json(name = "gasArgs")
|
||||
val gasArgs: GasArgs? = null,
|
||||
@Json(name = "ledgerWalletAPICompatible")
|
||||
val ledgerWalletAPICompatible: Boolean? = null,
|
||||
) {
|
||||
data class GasArgs(
|
||||
// cosmos-specific
|
||||
@Json(name = "gasPrice")
|
||||
val gasPrice: BigDecimal? = null,
|
||||
// EVM eip 1559 specific
|
||||
@Json(name = "type")
|
||||
val type: Int? = null,
|
||||
@Json(name = "maxFeePerGas")
|
||||
val maxFeePerGas: BigDecimal? = null,
|
||||
@Json(name = "maxPriorityFeePerGas")
|
||||
val maxPriorityFeePerGas: BigDecimal? = null,
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package com.tangem.datasource.api.stakekit.models.request
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
|
||||
data class SubmitTransactionHashRequestBody(
|
||||
@Json(name = "hash")
|
||||
val hash: String,
|
||||
)
|
||||
|
|
@ -5,26 +5,9 @@ import com.squareup.moshi.Json
|
|||
data class YieldBalanceRequestBody(
|
||||
@Json(name = "addresses") val addresses: Address,
|
||||
@Json(name = "args") val args: YieldBalanceRequestArgs,
|
||||
@Json(name = "integrationId") val integrationId: String? = null,
|
||||
@Json(name = "integrationId") val integrationId: String,
|
||||
) {
|
||||
|
||||
data class Address(
|
||||
@Json(name = "address") val address: String,
|
||||
@Json(name = "additionalAddresses") val additionalAddresses: AdditionalAddresses? = null,
|
||||
@Json(name = "explorerUrl") val explorerUrl: String,
|
||||
) {
|
||||
|
||||
data class AdditionalAddresses(
|
||||
@Json(name = "cosmosPubKey") val cosmosPubKey: String? = null,
|
||||
@Json(name = "binanceBeaconAddress") val binanceBeaconAddress: String? = null,
|
||||
@Json(name = "stakeAccounts") val stakeAccounts: List<String>? = null,
|
||||
@Json(name = "lidoStakeAccounts") val lidoStakeAccounts: List<String>? = null,
|
||||
@Json(name = "tezosPubKey") val tezosPubKey: String? = null,
|
||||
@Json(name = "cAddressBech") val cAddressBech: String? = null,
|
||||
@Json(name = "pAddressBech") val pAddressBech: String? = null,
|
||||
)
|
||||
}
|
||||
|
||||
data class YieldBalanceRequestArgs(
|
||||
@Json(name = "validatorAddresses") val validatorAddresses: List<String>,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -2,12 +2,12 @@ package com.tangem.datasource.api.stakekit.models.response
|
|||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import com.tangem.datasource.api.stakekit.models.response.model.Yield
|
||||
import com.tangem.datasource.api.stakekit.models.response.model.YieldDTO
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class EnabledYieldsResponse(
|
||||
@Json(name = "data")
|
||||
val data: List<Yield>,
|
||||
val data: List<YieldDTO>,
|
||||
@Json(name = "hasNextPage")
|
||||
val hasNextPage: Boolean,
|
||||
@Json(name = "limit")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
package com.tangem.datasource.api.stakekit.models.response
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import com.tangem.datasource.api.stakekit.models.response.model.action.StakingActionStatusDTO
|
||||
import com.tangem.datasource.api.stakekit.models.response.model.action.StakingActionTypeDTO
|
||||
import com.tangem.datasource.api.stakekit.models.response.model.transaction.StakingTransactionDTO
|
||||
import org.joda.time.DateTime
|
||||
import java.math.BigDecimal
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class EnterActionResponse(
|
||||
@Json(name = "id")
|
||||
val id: String,
|
||||
@Json(name = "integrationId")
|
||||
val integrationId: String,
|
||||
@Json(name = "status")
|
||||
val status: StakingActionStatusDTO,
|
||||
@Json(name = "type")
|
||||
val type: StakingActionTypeDTO,
|
||||
@Json(name = "currentStepIndex")
|
||||
val currentStepIndex: Int,
|
||||
@Json(name = "amount")
|
||||
val amount: BigDecimal,
|
||||
@Json(name = "validatorAddress")
|
||||
val validatorAddress: String?,
|
||||
@Json(name = "validatorAddresses")
|
||||
val validatorAddresses: List<String>?,
|
||||
@Json(name = "transactions")
|
||||
val transactions: List<StakingTransactionDTO>?,
|
||||
@Json(name = "createdAt")
|
||||
val createdAt: DateTime,
|
||||
)
|
||||
|
|
@ -4,13 +4,13 @@ import com.squareup.moshi.Json
|
|||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class AddressArgument(
|
||||
data class AddressArgumentDTO(
|
||||
@Json(name = "required")
|
||||
val required: Boolean,
|
||||
@Json(name = "network")
|
||||
val network: String? = null,
|
||||
@Json(name = "minimum")
|
||||
val minimum: Int? = null,
|
||||
val minimum: Double? = null,
|
||||
@Json(name = "maximum")
|
||||
val maximum: Int? = null,
|
||||
val maximum: Double? = null,
|
||||
)
|
||||
|
|
@ -0,0 +1,205 @@
|
|||
package com.tangem.datasource.api.stakekit.models.response.model
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
|
||||
enum class NetworkTypeDTO {
|
||||
@Json(name = "avalanche-c")
|
||||
AVALANCHE_C,
|
||||
|
||||
@Json(name = "avalanche-atomic")
|
||||
AVALANCHE_ATOMIC,
|
||||
|
||||
@Json(name = "avalanche-p")
|
||||
AVALANCHE_P,
|
||||
|
||||
@Json(name = "arbitrum")
|
||||
ARBITRUM,
|
||||
|
||||
@Json(name = "binance")
|
||||
BINANCE,
|
||||
|
||||
@Json(name = "celo")
|
||||
CELO,
|
||||
|
||||
@Json(name = "ethereum")
|
||||
ETHEREUM,
|
||||
|
||||
@Json(name = "ethereum-goerli")
|
||||
ETHEREUM_GOERLI,
|
||||
|
||||
@Json(name = "ethereum-holesky")
|
||||
ETHEREUM_HOLESKY,
|
||||
|
||||
@Json(name = "fantom")
|
||||
FANTOM,
|
||||
|
||||
@Json(name = "harmony")
|
||||
HARMONY,
|
||||
|
||||
@Json(name = "optimism")
|
||||
OPTIMISM,
|
||||
|
||||
@Json(name = "polygon")
|
||||
POLYGON,
|
||||
|
||||
@Json(name = "gnosis")
|
||||
GNOSIS,
|
||||
|
||||
@Json(name = "moonriver")
|
||||
MOONRIVER,
|
||||
|
||||
@Json(name = "okc")
|
||||
OKC,
|
||||
|
||||
@Json(name = "zksync")
|
||||
ZKSYNC,
|
||||
|
||||
@Json(name = "viction")
|
||||
VICTION,
|
||||
|
||||
@Json(name = "agoric")
|
||||
AGORIC,
|
||||
|
||||
@Json(name = "akash")
|
||||
AKASH,
|
||||
|
||||
@Json(name = "axelar")
|
||||
AXELAR,
|
||||
|
||||
@Json(name = "band-protocol")
|
||||
BAND_PROTOCOL,
|
||||
|
||||
@Json(name = "bitsong")
|
||||
BITSONG,
|
||||
|
||||
@Json(name = "canto")
|
||||
CANTO,
|
||||
|
||||
@Json(name = "chihuahua")
|
||||
CHIHUAHUA,
|
||||
|
||||
@Json(name = "comdex")
|
||||
COMDEX,
|
||||
|
||||
@Json(name = "coreum")
|
||||
COREUM,
|
||||
|
||||
@Json(name = "cosmos")
|
||||
COSMOS,
|
||||
|
||||
@Json(name = "crescent")
|
||||
CRESCENT,
|
||||
|
||||
@Json(name = "cronos")
|
||||
CRONOS,
|
||||
|
||||
@Json(name = "cudos")
|
||||
CUDOS,
|
||||
|
||||
@Json(name = "desmos")
|
||||
DESMOS,
|
||||
|
||||
@Json(name = "dydx")
|
||||
DYDX,
|
||||
|
||||
@Json(name = "evmos")
|
||||
EVMOS,
|
||||
|
||||
@Json(name = "fetch-ai")
|
||||
FETCH_AI,
|
||||
|
||||
@Json(name = "gravity-bridge")
|
||||
GRAVITY_BRIDGE,
|
||||
|
||||
@Json(name = "injective")
|
||||
INJECTIVE,
|
||||
|
||||
@Json(name = "irisnet")
|
||||
IRISNET,
|
||||
|
||||
@Json(name = "juno")
|
||||
JUNO,
|
||||
|
||||
@Json(name = "kava")
|
||||
KAVA,
|
||||
|
||||
@Json(name = "ki-network")
|
||||
KI_NETWORK,
|
||||
|
||||
@Json(name = "mars-protocol")
|
||||
MARS_PROTOCOL,
|
||||
|
||||
@Json(name = "nym")
|
||||
NYM,
|
||||
|
||||
@Json(name = "okex-chain")
|
||||
OKEX_CHAIN,
|
||||
|
||||
@Json(name = "onomy")
|
||||
ONOMY,
|
||||
|
||||
@Json(name = "osmosis")
|
||||
OSMOSIS,
|
||||
|
||||
@Json(name = "persistence")
|
||||
PERSISTENCE,
|
||||
|
||||
@Json(name = "quicksilver")
|
||||
QUICKSILVER,
|
||||
|
||||
@Json(name = "regen")
|
||||
REGEN,
|
||||
|
||||
@Json(name = "secret")
|
||||
SECRET,
|
||||
|
||||
@Json(name = "sentinel")
|
||||
SENTINEL,
|
||||
|
||||
@Json(name = "sommelier")
|
||||
SOMMELIER,
|
||||
|
||||
@Json(name = "stafi")
|
||||
STAFI,
|
||||
|
||||
@Json(name = "stargaze")
|
||||
STARGAZE,
|
||||
|
||||
@Json(name = "stride")
|
||||
STRIDE,
|
||||
|
||||
@Json(name = "teritori")
|
||||
TERITORI,
|
||||
|
||||
@Json(name = "tgrade")
|
||||
TGRADE,
|
||||
|
||||
@Json(name = "umee")
|
||||
UMEE,
|
||||
|
||||
@Json(name = "polkadot")
|
||||
POLKADOT,
|
||||
|
||||
@Json(name = "kusama")
|
||||
KUSAMA,
|
||||
|
||||
@Json(name = "westend")
|
||||
WESTEND,
|
||||
|
||||
@Json(name = "binancebeacon")
|
||||
BINANCEBEACON,
|
||||
|
||||
@Json(name = "near")
|
||||
NEAR,
|
||||
|
||||
@Json(name = "solana")
|
||||
SOLANA,
|
||||
|
||||
@Json(name = "tezos")
|
||||
TEZOS,
|
||||
|
||||
@Json(name = "tron")
|
||||
TRON,
|
||||
|
||||
UNKNOWN,
|
||||
}
|
||||
|
|
@ -1,218 +0,0 @@
|
|||
package com.tangem.datasource.api.stakekit.models.response.model
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Token(
|
||||
@Json(name = "name") val name: String,
|
||||
@Json(name = "network") val network: NetworkType,
|
||||
@Json(name = "symbol") val symbol: String,
|
||||
@Json(name = "decimals") val decimals: Int,
|
||||
@Json(name = "address") val address: String?,
|
||||
@Json(name = "coinGeckoId") val coinGeckoId: String?,
|
||||
@Json(name = "logoURI") val logoURI: String?,
|
||||
@Json(name = "isPoints") val isPoints: Boolean?,
|
||||
) {
|
||||
enum class NetworkType {
|
||||
@Json(name = "avalanche-c")
|
||||
AVALANCHE_C,
|
||||
|
||||
@Json(name = "avalanche-atomic")
|
||||
AVALANCHE_ATOMIC,
|
||||
|
||||
@Json(name = "avalanche-p")
|
||||
AVALANCHE_P,
|
||||
|
||||
@Json(name = "arbitrum")
|
||||
ARBITRUM,
|
||||
|
||||
@Json(name = "binance")
|
||||
BINANCE,
|
||||
|
||||
@Json(name = "celo")
|
||||
CELO,
|
||||
|
||||
@Json(name = "ethereum")
|
||||
ETHEREUM,
|
||||
|
||||
@Json(name = "ethereum-goerli")
|
||||
ETHEREUM_GOERLI,
|
||||
|
||||
@Json(name = "ethereum-holesky")
|
||||
ETHEREUM_HOLESKY,
|
||||
|
||||
@Json(name = "fantom")
|
||||
FANTOM,
|
||||
|
||||
@Json(name = "harmony")
|
||||
HARMONY,
|
||||
|
||||
@Json(name = "optimism")
|
||||
OPTIMISM,
|
||||
|
||||
@Json(name = "polygon")
|
||||
POLYGON,
|
||||
|
||||
@Json(name = "gnosis")
|
||||
GNOSIS,
|
||||
|
||||
@Json(name = "moonriver")
|
||||
MOONRIVER,
|
||||
|
||||
@Json(name = "okc")
|
||||
OKC,
|
||||
|
||||
@Json(name = "zksync")
|
||||
ZKSYNC,
|
||||
|
||||
@Json(name = "viction")
|
||||
VICTION,
|
||||
|
||||
@Json(name = "agoric")
|
||||
AGORIC,
|
||||
|
||||
@Json(name = "akash")
|
||||
AKASH,
|
||||
|
||||
@Json(name = "axelar")
|
||||
AXELAR,
|
||||
|
||||
@Json(name = "band-protocol")
|
||||
BAND_PROTOCOL,
|
||||
|
||||
@Json(name = "bitsong")
|
||||
BITSONG,
|
||||
|
||||
@Json(name = "canto")
|
||||
CANTO,
|
||||
|
||||
@Json(name = "chihuahua")
|
||||
CHIHUAHUA,
|
||||
|
||||
@Json(name = "comdex")
|
||||
COMDEX,
|
||||
|
||||
@Json(name = "coreum")
|
||||
COREUM,
|
||||
|
||||
@Json(name = "cosmos")
|
||||
COSMOS,
|
||||
|
||||
@Json(name = "crescent")
|
||||
CRESCENT,
|
||||
|
||||
@Json(name = "cronos")
|
||||
CRONOS,
|
||||
|
||||
@Json(name = "cudos")
|
||||
CUDOS,
|
||||
|
||||
@Json(name = "desmos")
|
||||
DESMOS,
|
||||
|
||||
@Json(name = "dydx")
|
||||
DYDX,
|
||||
|
||||
@Json(name = "evmos")
|
||||
EVMOS,
|
||||
|
||||
@Json(name = "fetch-ai")
|
||||
FETCH_AI,
|
||||
|
||||
@Json(name = "gravity-bridge")
|
||||
GRAVITY_BRIDGE,
|
||||
|
||||
@Json(name = "injective")
|
||||
INJECTIVE,
|
||||
|
||||
@Json(name = "irisnet")
|
||||
IRISNET,
|
||||
|
||||
@Json(name = "juno")
|
||||
JUNO,
|
||||
|
||||
@Json(name = "kava")
|
||||
KAVA,
|
||||
|
||||
@Json(name = "ki-network")
|
||||
KI_NETWORK,
|
||||
|
||||
@Json(name = "mars-protocol")
|
||||
MARS_PROTOCOL,
|
||||
|
||||
@Json(name = "nym")
|
||||
NYM,
|
||||
|
||||
@Json(name = "okex-chain")
|
||||
OKEX_CHAIN,
|
||||
|
||||
@Json(name = "onomy")
|
||||
ONOMY,
|
||||
|
||||
@Json(name = "osmosis")
|
||||
OSMOSIS,
|
||||
|
||||
@Json(name = "persistence")
|
||||
PERSISTENCE,
|
||||
|
||||
@Json(name = "quicksilver")
|
||||
QUICKSILVER,
|
||||
|
||||
@Json(name = "regen")
|
||||
REGEN,
|
||||
|
||||
@Json(name = "secret")
|
||||
SECRET,
|
||||
|
||||
@Json(name = "sentinel")
|
||||
SENTINEL,
|
||||
|
||||
@Json(name = "sommelier")
|
||||
SOMMELIER,
|
||||
|
||||
@Json(name = "stafi")
|
||||
STAFI,
|
||||
|
||||
@Json(name = "stargaze")
|
||||
STARGAZE,
|
||||
|
||||
@Json(name = "stride")
|
||||
STRIDE,
|
||||
|
||||
@Json(name = "teritori")
|
||||
TERITORI,
|
||||
|
||||
@Json(name = "tgrade")
|
||||
TGRADE,
|
||||
|
||||
@Json(name = "umee")
|
||||
UMEE,
|
||||
|
||||
@Json(name = "polkadot")
|
||||
POLKADOT,
|
||||
|
||||
@Json(name = "kusama")
|
||||
KUSAMA,
|
||||
|
||||
@Json(name = "westend")
|
||||
WESTEND,
|
||||
|
||||
@Json(name = "binancebeacon")
|
||||
BINANCEBEACON,
|
||||
|
||||
@Json(name = "near")
|
||||
NEAR,
|
||||
|
||||
@Json(name = "solana")
|
||||
SOLANA,
|
||||
|
||||
@Json(name = "tezos")
|
||||
TEZOS,
|
||||
|
||||
@Json(name = "tron")
|
||||
TRON,
|
||||
|
||||
UNKNOWN,
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package com.tangem.datasource.api.stakekit.models.response.model
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class TokenDTO(
|
||||
@Json(name = "name")
|
||||
val name: String,
|
||||
@Json(name = "network")
|
||||
val network: NetworkTypeDTO,
|
||||
@Json(name = "symbol")
|
||||
val symbol: String,
|
||||
@Json(name = "decimals")
|
||||
val decimals: Int,
|
||||
@Json(name = "address")
|
||||
val address: String?,
|
||||
@Json(name = "coinGeckoId")
|
||||
val coinGeckoId: String?,
|
||||
@Json(name = "logoURI")
|
||||
val logoURI: String?,
|
||||
@Json(name = "isPoints")
|
||||
val isPoints: Boolean?,
|
||||
)
|
||||
|
|
@ -4,7 +4,7 @@ import com.squareup.moshi.Json
|
|||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class TokenWithYield(
|
||||
@Json(name = "token") val token: Token,
|
||||
data class TokenWithYieldDTO(
|
||||
@Json(name = "token") val token: TokenDTO,
|
||||
@Json(name = "availableYields") val availableYieldIds: List<String>,
|
||||
)
|
||||
|
|
@ -1,138 +0,0 @@
|
|||
package com.tangem.datasource.api.stakekit.models.response.model
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import org.joda.time.DateTime
|
||||
import java.math.BigDecimal
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class YieldBalanceWrapper(
|
||||
@Json(name = "balances")
|
||||
val balances: List<Balance>,
|
||||
@Json(name = "integrationId")
|
||||
val integrationId: String?,
|
||||
) {
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Balance(
|
||||
@Json(name = "groupId")
|
||||
val groupId: String,
|
||||
@Json(name = "type")
|
||||
val type: BalanceType,
|
||||
@Json(name = "amount")
|
||||
val amount: BigDecimal,
|
||||
@Json(name = "date")
|
||||
val date: DateTime?,
|
||||
@Json(name = "pricePerShare")
|
||||
val pricePerShare: BigDecimal,
|
||||
@Json(name = "pendingActions")
|
||||
val pendingActions: List<PendingAction>,
|
||||
@Json(name = "token")
|
||||
val token: Token,
|
||||
@Json(name = "validatorAddress")
|
||||
val validatorAddress: String?,
|
||||
@Json(name = "validatorAddresses")
|
||||
val validatorAddresses: List<String>?,
|
||||
@Json(name = "providerId")
|
||||
val providerId: String?,
|
||||
) {
|
||||
|
||||
enum class BalanceType {
|
||||
@Json(name = "available")
|
||||
AVAILABLE,
|
||||
|
||||
@Json(name = "staked")
|
||||
STAKED,
|
||||
|
||||
@Json(name = "unstaking")
|
||||
UNSTAKING,
|
||||
|
||||
@Json(name = "unstaked")
|
||||
UNSTAKED,
|
||||
|
||||
@Json(name = "preparing")
|
||||
PREPARING,
|
||||
|
||||
@Json(name = "rewards")
|
||||
REWARDS,
|
||||
|
||||
@Json(name = "locked")
|
||||
LOCKED,
|
||||
|
||||
@Json(name = "unlocking")
|
||||
UNLOCKING,
|
||||
}
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class PendingAction(
|
||||
@Json(name = "type")
|
||||
val type: StakingActionType,
|
||||
@Json(name = "passthrough")
|
||||
val passthrough: String,
|
||||
@Json(name = "args")
|
||||
val args: PendingActionArgs?,
|
||||
) {
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class PendingActionArgs(
|
||||
@Json(name = "amount")
|
||||
val amount: Amount?,
|
||||
@Json(name = "duration")
|
||||
val duration: Duration?,
|
||||
@Json(name = "validatorAddress")
|
||||
val validatorAddress: Required?,
|
||||
@Json(name = "validatorAddresses")
|
||||
val validatorAddresses: Required?,
|
||||
@Json(name = "nfts")
|
||||
val nfts: List<Nft>?,
|
||||
@Json(name = "tronResource")
|
||||
val tronResource: TronResource?,
|
||||
@Json(name = "signatureVerification")
|
||||
val signatureVerification: Required?,
|
||||
) {
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Amount(
|
||||
@Json(name = "required")
|
||||
val required: Boolean,
|
||||
@Json(name = "minimum")
|
||||
val minimum: BigDecimal?,
|
||||
@Json(name = "maximum")
|
||||
val maximum: BigDecimal?,
|
||||
)
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Duration(
|
||||
@Json(name = "required")
|
||||
val required: Boolean,
|
||||
@Json(name = "minimum")
|
||||
val minimum: Int?,
|
||||
@Json(name = "maximum")
|
||||
val maximum: Int?,
|
||||
)
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Nft(
|
||||
@Json(name = "baycId")
|
||||
val baycId: Required?,
|
||||
@Json(name = "maycId")
|
||||
val maycId: Required?,
|
||||
@Json(name = "bakcId")
|
||||
val bakcId: Required?,
|
||||
)
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class TronResource(
|
||||
@Json(name = "required")
|
||||
val required: Boolean,
|
||||
@Json(name = "options")
|
||||
val options: List<String>,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Required(
|
||||
@Json(name = "required")
|
||||
val required: Boolean,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,140 @@
|
|||
package com.tangem.datasource.api.stakekit.models.response.model
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import com.tangem.datasource.api.stakekit.models.response.model.action.StakingActionTypeDTO
|
||||
import org.joda.time.DateTime
|
||||
import java.math.BigDecimal
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class YieldBalanceWrapperDTO(
|
||||
@Json(name = "balances")
|
||||
val balances: List<BalanceDTO>,
|
||||
@Json(name = "integrationId")
|
||||
val integrationId: String?,
|
||||
)
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class BalanceDTO(
|
||||
@Json(name = "groupId")
|
||||
val groupId: String,
|
||||
@Json(name = "type")
|
||||
val type: BalanceType,
|
||||
@Json(name = "amount")
|
||||
val amount: BigDecimal,
|
||||
@Json(name = "date")
|
||||
val date: DateTime?,
|
||||
@Json(name = "pricePerShare")
|
||||
val pricePerShare: BigDecimal,
|
||||
@Json(name = "pendingActions")
|
||||
val pendingActions: List<PendingAction>,
|
||||
@Json(name = "token")
|
||||
val tokenDTO: TokenDTO,
|
||||
@Json(name = "validatorAddress")
|
||||
val validatorAddress: String?,
|
||||
@Json(name = "validatorAddresses")
|
||||
val validatorAddresses: List<String>?,
|
||||
@Json(name = "providerId")
|
||||
val providerId: String?,
|
||||
) {
|
||||
|
||||
enum class BalanceType {
|
||||
@Json(name = "available")
|
||||
AVAILABLE,
|
||||
|
||||
@Json(name = "staked")
|
||||
STAKED,
|
||||
|
||||
@Json(name = "unstaking")
|
||||
UNSTAKING,
|
||||
|
||||
@Json(name = "unstaked")
|
||||
UNSTAKED,
|
||||
|
||||
@Json(name = "preparing")
|
||||
PREPARING,
|
||||
|
||||
@Json(name = "rewards")
|
||||
REWARDS,
|
||||
|
||||
@Json(name = "locked")
|
||||
LOCKED,
|
||||
|
||||
@Json(name = "unlocking")
|
||||
UNLOCKING,
|
||||
|
||||
UNKNOWN,
|
||||
}
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class PendingAction(
|
||||
@Json(name = "type")
|
||||
val type: StakingActionTypeDTO,
|
||||
@Json(name = "passthrough")
|
||||
val passthrough: String,
|
||||
@Json(name = "args")
|
||||
val args: PendingActionArgs?,
|
||||
) {
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class PendingActionArgs(
|
||||
@Json(name = "amount")
|
||||
val amount: Amount?,
|
||||
@Json(name = "duration")
|
||||
val duration: Duration?,
|
||||
@Json(name = "validatorAddress")
|
||||
val validatorAddress: Required?,
|
||||
@Json(name = "validatorAddresses")
|
||||
val validatorAddresses: Required?,
|
||||
@Json(name = "nfts")
|
||||
val nfts: List<Nft>?,
|
||||
@Json(name = "tronResource")
|
||||
val tronResource: TronResource?,
|
||||
@Json(name = "signatureVerification")
|
||||
val signatureVerification: Required?,
|
||||
) {
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Amount(
|
||||
@Json(name = "required")
|
||||
val required: Boolean,
|
||||
@Json(name = "minimum")
|
||||
val minimum: BigDecimal?,
|
||||
@Json(name = "maximum")
|
||||
val maximum: BigDecimal?,
|
||||
)
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Duration(
|
||||
@Json(name = "required")
|
||||
val required: Boolean,
|
||||
@Json(name = "minimum")
|
||||
val minimum: Int?,
|
||||
@Json(name = "maximum")
|
||||
val maximum: Int?,
|
||||
)
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Nft(
|
||||
@Json(name = "baycId")
|
||||
val baycId: Required?,
|
||||
@Json(name = "maycId")
|
||||
val maycId: Required?,
|
||||
@Json(name = "bakcId")
|
||||
val bakcId: Required?,
|
||||
)
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class TronResource(
|
||||
@Json(name = "required")
|
||||
val required: Boolean,
|
||||
@Json(name = "options")
|
||||
val options: List<String>,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Required(
|
||||
@Json(name = "required")
|
||||
val required: Boolean,
|
||||
)
|
||||
}
|
||||
|
|
@ -1,138 +0,0 @@
|
|||
package com.tangem.datasource.api.stakekit.models.response.model
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import org.joda.time.DateTime
|
||||
import java.math.BigDecimal
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class YieldBalances(
|
||||
@Json(name = "balances")
|
||||
val balances: List<Balance>,
|
||||
@Json(name = "integrationId")
|
||||
val integrationId: String,
|
||||
) {
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Balance(
|
||||
@Json(name = "groupId")
|
||||
val groupId: String,
|
||||
@Json(name = "type")
|
||||
val type: BalanceType,
|
||||
@Json(name = "amount")
|
||||
val amount: BigDecimal,
|
||||
@Json(name = "date")
|
||||
val date: DateTime?,
|
||||
@Json(name = "pricePerShare")
|
||||
val pricePerShare: BigDecimal,
|
||||
@Json(name = "pendingActions")
|
||||
val pendingActions: List<PendingAction>,
|
||||
@Json(name = "token")
|
||||
val token: Token,
|
||||
@Json(name = "validatorAddress")
|
||||
val validatorAddress: String?,
|
||||
@Json(name = "validatorAddresses")
|
||||
val validatorAddresses: List<String>?,
|
||||
@Json(name = "providerId")
|
||||
val providerId: String?,
|
||||
) {
|
||||
|
||||
enum class BalanceType {
|
||||
@Json(name = "available")
|
||||
AVAILABLE,
|
||||
|
||||
@Json(name = "staked")
|
||||
STAKED,
|
||||
|
||||
@Json(name = "unstaking")
|
||||
UNSTAKING,
|
||||
|
||||
@Json(name = "unstaked")
|
||||
UNSTAKED,
|
||||
|
||||
@Json(name = "preparing")
|
||||
PREPARING,
|
||||
|
||||
@Json(name = "rewards")
|
||||
REWARDS,
|
||||
|
||||
@Json(name = "locked")
|
||||
LOCKED,
|
||||
|
||||
@Json(name = "unlocking")
|
||||
UNLOCKING,
|
||||
}
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class PendingAction(
|
||||
@Json(name = "type")
|
||||
val type: StakingActionType,
|
||||
@Json(name = "passthrough")
|
||||
val passthrough: String,
|
||||
@Json(name = "args")
|
||||
val args: PendingActionArgs?,
|
||||
) {
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class PendingActionArgs(
|
||||
@Json(name = "amount")
|
||||
val amount: Amount?,
|
||||
@Json(name = "duration")
|
||||
val duration: Duration?,
|
||||
@Json(name = "validatorAddress")
|
||||
val validatorAddress: Required?,
|
||||
@Json(name = "validatorAddresses")
|
||||
val validatorAddresses: Required?,
|
||||
@Json(name = "nfts")
|
||||
val nfts: List<Nft>?,
|
||||
@Json(name = "tronResource")
|
||||
val tronResource: TronResource?,
|
||||
@Json(name = "signatureVerification")
|
||||
val signatureVerification: Required?,
|
||||
) {
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Amount(
|
||||
@Json(name = "required")
|
||||
val required: Boolean,
|
||||
@Json(name = "minimum")
|
||||
val minimum: BigDecimal?,
|
||||
@Json(name = "maximum")
|
||||
val maximum: BigDecimal?,
|
||||
)
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Duration(
|
||||
@Json(name = "required")
|
||||
val required: Boolean,
|
||||
@Json(name = "minimum")
|
||||
val minimum: Int?,
|
||||
@Json(name = "maximum")
|
||||
val maximum: Int?,
|
||||
)
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Nft(
|
||||
@Json(name = "baycId")
|
||||
val baycId: Required?,
|
||||
@Json(name = "maycId")
|
||||
val maycId: Required?,
|
||||
@Json(name = "bakcId")
|
||||
val bakcId: Required?,
|
||||
)
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class TronResource(
|
||||
@Json(name = "required")
|
||||
val required: Boolean,
|
||||
@Json(name = "options")
|
||||
val options: List<String>,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Required(
|
||||
@Json(name = "required")
|
||||
val required: Boolean,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -5,33 +5,33 @@ import com.squareup.moshi.JsonClass
|
|||
import java.math.BigDecimal
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Yield(
|
||||
data class YieldDTO(
|
||||
@Json(name = "id")
|
||||
val id: String,
|
||||
@Json(name = "token")
|
||||
val token: Token,
|
||||
val token: TokenDTO,
|
||||
@Json(name = "tokens")
|
||||
val tokens: List<Token>,
|
||||
val tokens: List<TokenDTO>,
|
||||
@Json(name = "args")
|
||||
val args: Args,
|
||||
val args: ArgsDTO,
|
||||
@Json(name = "status")
|
||||
val status: Status,
|
||||
val status: StatusDTO,
|
||||
@Json(name = "apy")
|
||||
val apy: BigDecimal,
|
||||
@Json(name = "rewardRate")
|
||||
val rewardRate: Double,
|
||||
@Json(name = "rewardType")
|
||||
val rewardType: RewardType,
|
||||
val rewardType: RewardTypeDTO,
|
||||
@Json(name = "metadata")
|
||||
val metadata: Metadata,
|
||||
val metadata: MetadataDTO,
|
||||
@Json(name = "validators")
|
||||
val validators: List<Validator>,
|
||||
val validators: List<ValidatorDTO>,
|
||||
@Json(name = "isAvailable")
|
||||
val isAvailable: Boolean,
|
||||
) {
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Status(
|
||||
data class StatusDTO(
|
||||
@Json(name = "enter")
|
||||
val enter: Boolean,
|
||||
@Json(name = "exit")
|
||||
|
|
@ -39,7 +39,7 @@ data class Yield(
|
|||
)
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Args(
|
||||
data class ArgsDTO(
|
||||
@Json(name = "enter")
|
||||
val enter: Enter,
|
||||
@Json(name = "exit")
|
||||
|
|
@ -50,20 +50,20 @@ data class Yield(
|
|||
@Json(name = "addresses")
|
||||
val addresses: Addresses,
|
||||
@Json(name = "args")
|
||||
val args: Map<String, AddressArgument>,
|
||||
val args: Map<String, AddressArgumentDTO>,
|
||||
) {
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Addresses(
|
||||
@Json(name = "address")
|
||||
val address: AddressArgument,
|
||||
val address: AddressArgumentDTO,
|
||||
@Json(name = "additionalAddresses")
|
||||
val additionalAddresses: Map<String, AddressArgument>? = null,
|
||||
val additionalAddresses: Map<String, AddressArgumentDTO>? = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Validator(
|
||||
data class ValidatorDTO(
|
||||
@Json(name = "address")
|
||||
val address: String,
|
||||
@Json(name = "status")
|
||||
|
|
@ -75,7 +75,7 @@ data class Yield(
|
|||
@Json(name = "website")
|
||||
val website: String?,
|
||||
@Json(name = "apr")
|
||||
val apr: Double?,
|
||||
val apr: BigDecimal?,
|
||||
@Json(name = "commission")
|
||||
val commission: Double?,
|
||||
@Json(name = "stakedBalance")
|
||||
|
|
@ -87,7 +87,7 @@ data class Yield(
|
|||
)
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Metadata(
|
||||
data class MetadataDTO(
|
||||
@Json(name = "name")
|
||||
val name: String,
|
||||
@Json(name = "logoURI")
|
||||
|
|
@ -97,19 +97,19 @@ data class Yield(
|
|||
@Json(name = "documentation")
|
||||
val documentation: String?,
|
||||
@Json(name = "gasFeeToken")
|
||||
val gasFeeToken: Token,
|
||||
val gasFeeTokenDTO: TokenDTO,
|
||||
@Json(name = "token")
|
||||
val token: Token,
|
||||
val tokenDTO: TokenDTO,
|
||||
@Json(name = "tokens")
|
||||
val tokens: List<Token>,
|
||||
val tokensDTO: List<TokenDTO>,
|
||||
@Json(name = "type")
|
||||
val type: String,
|
||||
@Json(name = "rewardSchedule")
|
||||
val rewardSchedule: String,
|
||||
@Json(name = "cooldownPeriod")
|
||||
val cooldownPeriod: Period,
|
||||
val cooldownPeriod: PeriodDTO,
|
||||
@Json(name = "warmupPeriod")
|
||||
val warmupPeriod: Period,
|
||||
val warmupPeriod: PeriodDTO,
|
||||
@Json(name = "rewardClaiming")
|
||||
val rewardClaiming: String,
|
||||
@Json(name = "defaultValidator")
|
||||
|
|
@ -119,28 +119,30 @@ data class Yield(
|
|||
@Json(name = "supportsMultipleValidators")
|
||||
val supportsMultipleValidators: Boolean,
|
||||
@Json(name = "revshare")
|
||||
val revshare: Enabled,
|
||||
val revshare: EnabledDTO,
|
||||
@Json(name = "fee")
|
||||
val fee: Enabled,
|
||||
val fee: EnabledDTO,
|
||||
) {
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Period(
|
||||
data class PeriodDTO(
|
||||
@Json(name = "days")
|
||||
val days: Int,
|
||||
)
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Enabled(
|
||||
data class EnabledDTO(
|
||||
@Json(name = "enabled")
|
||||
val enabled: Boolean,
|
||||
)
|
||||
}
|
||||
|
||||
enum class RewardType {
|
||||
enum class RewardTypeDTO {
|
||||
@Json(name = "apy")
|
||||
APY, // auto
|
||||
APY, // compound rate
|
||||
@Json(name = "apr")
|
||||
APR, // manual
|
||||
APR, // simple rate,
|
||||
|
||||
UNKNOWN,
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package com.tangem.datasource.api.stakekit.models.response.model.action
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
|
||||
enum class StakingActionStatusDTO {
|
||||
@Json(name = "CANCELED")
|
||||
CANCELED,
|
||||
|
||||
@Json(name = "CREATED")
|
||||
CREATED,
|
||||
|
||||
@Json(name = "WAITING_FOR_NEXT")
|
||||
WAITING_FOR_NEXT,
|
||||
|
||||
@Json(name = "PROCESSING")
|
||||
PROCESSING,
|
||||
|
||||
@Json(name = "FAILED")
|
||||
FAILED,
|
||||
|
||||
@Json(name = "SUCCESS")
|
||||
SUCCESS,
|
||||
|
||||
UNKNOWN,
|
||||
}
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
package com.tangem.datasource.api.stakekit.models.response.model
|
||||
package com.tangem.datasource.api.stakekit.models.response.model.action
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
|
||||
enum class StakingActionType {
|
||||
enum class StakingActionTypeDTO {
|
||||
@Json(name = "STAKE")
|
||||
STAKE,
|
||||
|
||||
|
|
@ -47,4 +47,6 @@ enum class StakingActionType {
|
|||
|
||||
@Json(name = "MIGRATE")
|
||||
MIGRATE,
|
||||
|
||||
UNKNOWN,
|
||||
}
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
package com.tangem.datasource.api.stakekit.models.response.model.error
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
|
||||
class StakeKitErrorResponse(
|
||||
@Json(name = "details")
|
||||
val details: StakeKitErrorDetailsDTO? = null,
|
||||
@Json(name = "message")
|
||||
val message: StakeKitErrorMessageDTO? = null,
|
||||
@Json(name = "level")
|
||||
val level: String? = null, // unused
|
||||
)
|
||||
|
||||
data class StakeKitErrorDetailsDTO(
|
||||
@Json(name = "arguments")
|
||||
val arguments: String? = null,
|
||||
@Json(name = "amount")
|
||||
val amount: String? = null,
|
||||
@Json(name = "yieldId")
|
||||
val yieldId: String? = null,
|
||||
)
|
||||
|
||||
enum class StakeKitErrorMessageDTO {
|
||||
@Json(name = "MissingArgumentsError")
|
||||
MISSING_ARGUMENTS_ERROR,
|
||||
|
||||
@Json(name = "MinimumAmountNotReached")
|
||||
MINIMUM_AMOUNT_NOT_REACHED,
|
||||
|
||||
@Json(name = "YieldUnderMaintenanceError")
|
||||
YIELD_UNDER_MAINTENANCE_ERROR,
|
||||
|
||||
@Json(name = "InsufficientFundsError")
|
||||
INSUFFICIENT_FUNDS_ERROR,
|
||||
|
||||
@Json(name = "StakedPositionNotFoundError")
|
||||
STAKED_POSITION_NOT_FOUND_ERROR,
|
||||
|
||||
@Json(name = "InvalidAmountSubmittedError")
|
||||
INVALID_AMOUNT_SUBMITTED_ERROR,
|
||||
|
||||
@Json(name = "BalanceUnavailableError")
|
||||
BALANCE_UNAVAILABLE_ERROR,
|
||||
|
||||
@Json(name = "GasPriceUnavailableError")
|
||||
GAS_PRICE_UNAVAILABLE_ERROR,
|
||||
|
||||
@Json(name = "NotImplementedError")
|
||||
NOT_IMPLEMENTED_ERROR,
|
||||
|
||||
@Json(name = "TokenNotFoundError")
|
||||
TOKEN_NOT_FOUND_ERROR,
|
||||
|
||||
@Json(name = "BroadcastTransactionError")
|
||||
BROADCAST_TRANSACTION_ERROR,
|
||||
|
||||
@Json(name = "MissingGasPriceStrategyError")
|
||||
MISSING_GAS_PRICE_STRATEGY_ERROR,
|
||||
|
||||
@Json(name = "SubstrateMalformedTransactionHashError")
|
||||
SUBSTRATE_MALFORMED_TRANSACTION_HASH_ERROR,
|
||||
|
||||
@Json(name = "TronMaximumAmountOfValidatorsExceededError")
|
||||
TRON_MAXIMUM_AMOUNT_OF_VALIDATORS_EXCEEDED_ERROR,
|
||||
|
||||
@Json(name = "SubstratePoolNotFoundError")
|
||||
SUBSTRATE_POOL_NOT_FOUND_ERROR,
|
||||
|
||||
@Json(name = "SubstrateBondedAmountTooLowError")
|
||||
SUBSTRATE_BONDED_AMOUNT_TOO_LOW_ERROR,
|
||||
|
||||
@Json(name = "TronMissingResourceTypeArgumentError")
|
||||
TRON_MISSING_RESOURCE_TYPE_ARGUMENT_ERROR,
|
||||
|
||||
@Json(name = "AaveV3PoolFrozenError")
|
||||
AAVE_V3_POOL_FROZEN_ERROR,
|
||||
|
||||
@Json(name = "AaveV3TokenPairNotFoundError")
|
||||
AAVE_V3_TOKEN_PAIR_NOT_FOUND_ERROR,
|
||||
|
||||
@Json(name = "YearnVaultAtMaxCapacityError")
|
||||
YEARN_VAULT_AT_MAX_CAPACITY_ERROR,
|
||||
|
||||
@Json(name = "StETHNoWithdrawalRequestsFoundError")
|
||||
STETH_NO_WITHDRAWAL_REQUESTS_FOUND_ERROR,
|
||||
|
||||
@Json(name = "MorphoLendingPoolPausedError")
|
||||
MORPHO_LENDING_POOL_PAUSED_ERROR,
|
||||
|
||||
@Json(name = "NonceUnavailableError")
|
||||
NONCE_UNAVAILABLE_ERROR,
|
||||
|
||||
@Json(name = "CosmosAcccountNotFoundError")
|
||||
COSMOS_ACCOUNT_NOT_FOUND_ERROR,
|
||||
|
||||
@Json(name = "AvalancheMissingAdditionalAddressesArgumentError")
|
||||
AVALANCHE_MISSING_ADDITIONAL_ADDRESSES_ARGUMENT_ERROR,
|
||||
|
||||
@Json(name = "AvalancheValidatorInfoNotFoundError")
|
||||
AVALANCHE_VALIDATOR_INFO_NOT_FOUND_ERROR,
|
||||
|
||||
@Json(name = "SolanaTransactionSignatureVerificationFailureError")
|
||||
SOLANA_TRANSACTION_SIGNATURE_VERIFICATION_FAILURE_ERROR,
|
||||
|
||||
@Json(name = "SolanaUnableTocreateStakeAccountError")
|
||||
SOLANA_UNABLE_TO_CREATE_STAKE_ACCOUNT_ERROR,
|
||||
|
||||
@Json(name = "SolanaStakeAmountTooLowError")
|
||||
SOLANA_STAKE_AMOUNT_TOO_LOW_ERROR,
|
||||
|
||||
@Json(name = "SolanaUnstakeAmountTooLowError")
|
||||
SOLANA_UNSTAKE_AMOUNT_TOO_LOW_ERROR,
|
||||
|
||||
@Json(name = "SolanaStakeAccountsNotFoundError")
|
||||
SOLANA_STAKE_ACCOUNTS_NOT_FOUND_ERROR,
|
||||
|
||||
@Json(name = "SolanaEligibleStakeAccountsNotFoundError")
|
||||
SOLANA_ELIGIBLE_STAKE_ACCOUNTS_NOT_FOUND_ERROR,
|
||||
|
||||
@Json(name = "TezosNoBalanceDelegatedError")
|
||||
TEZOS_NO_BALANCE_DELEGATED_ERROR,
|
||||
|
||||
@Json(name = "TezosMissingPubkeyArgumentError")
|
||||
TEZOS_MISSING_PUBKEY_ARGUMENT_ERROR,
|
||||
|
||||
@Json(name = "TezosEstimateRevealGasLimitError")
|
||||
TEZOS_ESTIMATE_REVEAL_GAS_LIMIT_ERROR,
|
||||
|
||||
@Json(name = "TezosBalanceAlreadyDelegatedError")
|
||||
TEZOS_BALANCE_ALREADY_DELEGATED_ERROR,
|
||||
|
||||
@Json(name = "BinanceAccountNotFoundError")
|
||||
BINANCE_ACCOUNT_NOT_FOUND_ERROR,
|
||||
|
||||
@Json(name = "BinanceMissingAccountNumberOrSequenceError")
|
||||
BINANCE_MISSING_ACCOUNT_NUMBER_OR_SEQUENCE_ERROR,
|
||||
|
||||
@Json(name = "GRTStakingDisabledError")
|
||||
GRT_STAKING_DISABLED_ERROR,
|
||||
|
||||
@Json(name = "GRTStakingDisabledLedgerLiveError")
|
||||
GRT_STAKING_DISABLED_LEDGER_LIVE_ERROR,
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package com.tangem.datasource.api.stakekit.models.response.model.transaction
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import com.tangem.datasource.api.stakekit.models.response.model.TokenDTO
|
||||
import java.math.BigDecimal
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class StakingGasEstimateDTO(
|
||||
@Json(name = "amount")
|
||||
val amount: BigDecimal,
|
||||
@Json(name = "token")
|
||||
val token: TokenDTO,
|
||||
@Json(name = "gasLimit")
|
||||
val gasLimit: String?,
|
||||
)
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
package com.tangem.datasource.api.stakekit.models.response.model.transaction
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import com.tangem.datasource.api.stakekit.models.response.model.NetworkTypeDTO
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class StakingTransactionDTO(
|
||||
@Json(name = "id")
|
||||
val id: String,
|
||||
@Json(name = "network")
|
||||
val network: NetworkTypeDTO,
|
||||
@Json(name = "status")
|
||||
val status: StakingTransactionStatusDTO,
|
||||
@Json(name = "type")
|
||||
val type: StakingTransactionTypeDTO,
|
||||
@Json(name = "hash")
|
||||
val hash: String?,
|
||||
@Json(name = "signedTransaction")
|
||||
val signedTransaction: String?,
|
||||
@Json(name = "unsignedTransaction")
|
||||
val unsignedTransaction: String?,
|
||||
@Json(name = "stepIndex")
|
||||
val stepIndex: Int,
|
||||
@Json(name = "error")
|
||||
val error: String?,
|
||||
@Json(name = "gasEstimate")
|
||||
val gasEstimate: StakingGasEstimateDTO?,
|
||||
@Json(name = "stakeId")
|
||||
val stakeId: String?,
|
||||
@Json(name = "explorerUrl")
|
||||
val explorerUrl: String?,
|
||||
@Json(name = "ledgerHwAppId")
|
||||
val ledgerHwAppId: String?,
|
||||
@Json(name = "isMessage")
|
||||
val isMessage: Boolean,
|
||||
)
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
package com.tangem.datasource.api.stakekit.models.response.model.transaction
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
|
||||
enum class StakingTransactionStatusDTO {
|
||||
@Json(name = "NOT_FOUND")
|
||||
NOT_FOUND,
|
||||
|
||||
@Json(name = "CREATED")
|
||||
CREATED,
|
||||
|
||||
@Json(name = "BLOCKED")
|
||||
BLOCKED,
|
||||
|
||||
@Json(name = "WAITING_FOR_SIGNATURE")
|
||||
WAITING_FOR_SIGNATURE,
|
||||
|
||||
@Json(name = "SIGNED")
|
||||
SIGNED,
|
||||
|
||||
@Json(name = "BROADCASTED")
|
||||
BROADCASTED,
|
||||
|
||||
@Json(name = "PENDING")
|
||||
PENDING,
|
||||
|
||||
@Json(name = "CONFIRMED")
|
||||
CONFIRMED,
|
||||
|
||||
@Json(name = "FAILED")
|
||||
FAILED,
|
||||
|
||||
@Json(name = "SKIPPED")
|
||||
SKIPPED,
|
||||
|
||||
UNKNOWN,
|
||||
}
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
package com.tangem.datasource.api.stakekit.models.response.model.transaction
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
|
||||
enum class StakingTransactionTypeDTO {
|
||||
@Json(name = "SWAP")
|
||||
SWAP,
|
||||
|
||||
@Json(name = "DEPOSIT")
|
||||
DEPOSIT,
|
||||
|
||||
@Json(name = "APPROVAL")
|
||||
APPROVAL,
|
||||
|
||||
@Json(name = "STAKE")
|
||||
STAKE,
|
||||
|
||||
@Json(name = "CLAIM_UNSTAKED")
|
||||
CLAIM_UNSTAKED,
|
||||
|
||||
@Json(name = "CLAIM_REWARDS")
|
||||
CLAIM_REWARDS,
|
||||
|
||||
@Json(name = "RESTAKE_REWARDS")
|
||||
RESTAKE_REWARDS,
|
||||
|
||||
@Json(name = "UNSTAKE")
|
||||
UNSTAKE,
|
||||
|
||||
@Json(name = "SPLIT")
|
||||
SPLIT,
|
||||
|
||||
@Json(name = "MERGE")
|
||||
MERGE,
|
||||
|
||||
@Json(name = "LOCK")
|
||||
LOCK,
|
||||
|
||||
@Json(name = "UNLOCK")
|
||||
UNLOCK,
|
||||
|
||||
@Json(name = "SUPPLY")
|
||||
SUPPLY,
|
||||
|
||||
@Json(name = "BRIDGE")
|
||||
BRIDGE,
|
||||
|
||||
@Json(name = "VOTE")
|
||||
VOTE,
|
||||
|
||||
@Json(name = "REVOKE")
|
||||
REVOKE,
|
||||
|
||||
@Json(name = "RESTAKE")
|
||||
RESTAKE,
|
||||
|
||||
@Json(name = "REBOND")
|
||||
REBOND,
|
||||
|
||||
@Json(name = "WITHDRAW")
|
||||
WITHDRAW,
|
||||
|
||||
@Json(name = "CREATE_ACCOUNT")
|
||||
CREATE_ACCOUNT,
|
||||
|
||||
@Json(name = "REVEAL")
|
||||
REVEAL,
|
||||
|
||||
@Json(name = "MIGRATE")
|
||||
MIGRATE,
|
||||
|
||||
@Json(name = "UTXO_P_TO_C_IMPORT")
|
||||
UTXO_P_TO_C_IMPORT,
|
||||
|
||||
@Json(name = "UTXO_C_TO_P_IMPORT")
|
||||
UTXO_C_TO_P_IMPORT,
|
||||
|
||||
@Json(name = "UNFREEZE_LEGACY")
|
||||
UNFREEZE_LEGACY,
|
||||
|
||||
@Json(name = "UNFREEZE_LEGACY_BANDWIDTH")
|
||||
UNFREEZE_LEGACY_BANDWIDTH,
|
||||
|
||||
@Json(name = "UNFREEZE_LEGACY_ENERGY")
|
||||
UNFREEZE_LEGACY_ENERGY,
|
||||
|
||||
@Json(name = "UNFREEZE_BANDWIDTH")
|
||||
UNFREEZE_BANDWIDTH,
|
||||
|
||||
@Json(name = "UNFREEZE_ENERGY")
|
||||
UNFREEZE_ENERGY,
|
||||
|
||||
@Json(name = "FREEZE_BANDWIDTH")
|
||||
FREEZE_BANDWIDTH,
|
||||
|
||||
@Json(name = "FREEZE_ENERGY")
|
||||
FREEZE_ENERGY,
|
||||
|
||||
@Json(name = "UNDELEGATE_BANDWIDTH")
|
||||
UNDELEGATE_BANDWIDTH,
|
||||
|
||||
@Json(name = "UNDELEGATE_ENERGY")
|
||||
UNDELEGATE_ENERGY,
|
||||
|
||||
@Json(name = "P2P_NODE_REQUEST")
|
||||
P2P_NODE_REQUEST,
|
||||
|
||||
@Json(name = "LUGANODES_PROVISION")
|
||||
LUGANODES_PROVISION,
|
||||
|
||||
@Json(name = "LUGANODES_EXIT_REQUEST")
|
||||
LUGANODES_EXIT_REQUEST,
|
||||
|
||||
@Json(name = "INFSTONES_PROVISION")
|
||||
INFSTONES_PROVISION,
|
||||
|
||||
@Json(name = "INFSTONES_EXIT_REQUEST")
|
||||
INFSTONES_EXIT_REQUEST,
|
||||
|
||||
@Json(name = "INFSTONES_CLAIM_REQUEST")
|
||||
INFSTONES_CLAIM_REQUEST,
|
||||
|
||||
UNKNOWN,
|
||||
}
|
||||
|
|
@ -12,6 +12,10 @@ data class QuotesResponse(
|
|||
@Json(name = "price")
|
||||
val price: BigDecimal?,
|
||||
@Json(name = "priceChange24h")
|
||||
val priceChange: BigDecimal?,
|
||||
val priceChange24h: BigDecimal?,
|
||||
@Json(name = "priceChange1w")
|
||||
val priceChange1w: BigDecimal?,
|
||||
@Json(name = "priceChange30d")
|
||||
val priceChange30d: BigDecimal?,
|
||||
)
|
||||
}
|
||||
|
|
@ -103,6 +103,7 @@ internal class ConfigManagerImpl @Inject constructor() : ConfigManager {
|
|||
polygonScanApiKey = configValues.polygonScanApiKey,
|
||||
bittensorDwellirApiKey = configValues.bittensorDwellirApiKey,
|
||||
bittensorOnfinalityApiKey = configValues.bittensorOnfinalityKey,
|
||||
koinosProApiKey = configValues.koinosProApiKey,
|
||||
),
|
||||
amplitudeApiKey = configValues.amplitudeApiKey,
|
||||
sprinklr = configValues.sprinklr,
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ class ConfigValueModel(
|
|||
val stakeKitApiKey: String?,
|
||||
@Json(name = "bittensorDwellirKey") val bittensorDwellirApiKey: String?,
|
||||
@Json(name = "bittensorOnfinalityKey") val bittensorOnfinalityKey: String?,
|
||||
@Json(name = "koinosProApiKey") val koinosProApiKey: String?,
|
||||
)
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
package com.tangem.datasource.di
|
||||
|
||||
import com.tangem.datasource.local.datastore.RuntimeDataStore
|
||||
import com.tangem.datasource.local.token.DefaultAssetsStore
|
||||
import com.tangem.datasource.local.token.AssetsStore
|
||||
import com.tangem.datasource.local.token.DefaultExpressAssetsStore
|
||||
import com.tangem.datasource.local.token.ExpressAssetsStore
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
|
|
@ -11,11 +11,11 @@ import javax.inject.Singleton
|
|||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
internal object AssetsStoreModule {
|
||||
internal object ExpressAssetsStoreModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideAssetsStore(): AssetsStore {
|
||||
return DefaultAssetsStore(dataStore = RuntimeDataStore())
|
||||
fun provideExpressAssetsStore(): ExpressAssetsStore {
|
||||
return DefaultExpressAssetsStore(dataStore = RuntimeDataStore())
|
||||
}
|
||||
}
|
||||
|
|
@ -4,11 +4,10 @@ import com.squareup.moshi.Moshi
|
|||
import com.squareup.moshi.adapters.PolymorphicJsonAdapterFactory
|
||||
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
|
||||
import com.tangem.common.json.MoshiJsonConverter
|
||||
import com.tangem.datasource.api.common.adapter.*
|
||||
import com.tangem.datasource.api.common.adapter.BigDecimalAdapter
|
||||
import com.tangem.datasource.api.common.adapter.DateTimeAdapter
|
||||
import com.tangem.datasource.api.common.adapter.LocalDateAdapter
|
||||
import com.tangem.datasource.api.common.adapter.UnknownEnumMoshiAdapter
|
||||
import com.tangem.datasource.api.stakekit.models.response.model.Token
|
||||
import com.tangem.datasource.config.models.ProviderModel
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
|
|
@ -35,10 +34,7 @@ class MoshiModule {
|
|||
.add(LocalDateAdapter())
|
||||
.add(DateTimeAdapter())
|
||||
.add(KotlinJsonAdapterFactory())
|
||||
.add(
|
||||
Token.NetworkType::class.java,
|
||||
UnknownEnumMoshiAdapter.create(Token.NetworkType::class.java, Token.NetworkType.UNKNOWN),
|
||||
)
|
||||
.addStakeKitEnumFallbackAdapters()
|
||||
.build()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import com.squareup.moshi.Moshi
|
|||
import com.tangem.datasource.BuildConfig
|
||||
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.stakekit.StakeKitApi
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechApiV2
|
||||
|
|
@ -123,7 +124,31 @@ class NetworkModule {
|
|||
context = context,
|
||||
appVersionProvider = appVersionProvider,
|
||||
baseUrl = PROD_V1_TANGEM_TECH_BASE_URL,
|
||||
timeoutSeconds = TANGEM_TECH_SERVICE_TIMEOUT_SECONDS,
|
||||
timeouts = Timeouts(
|
||||
callTimeoutSeconds = TANGEM_TECH_SERVICE_TIMEOUT_SECONDS,
|
||||
),
|
||||
requestHeaders = listOf(AppVersionPlatformHeaders(appVersionProvider)),
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@DevTangemApi
|
||||
@Singleton
|
||||
fun provideTangemTechMarketsApi(
|
||||
@NetworkMoshi moshi: Moshi,
|
||||
@ApplicationContext context: Context,
|
||||
appVersionProvider: AppVersionProvider,
|
||||
): TangemTechMarketsApi {
|
||||
return provideTangemTechApiInternal(
|
||||
moshi = moshi,
|
||||
context = context,
|
||||
appVersionProvider = appVersionProvider,
|
||||
baseUrl = DEV_V1_TANGEM_TECH_BASE_URL,
|
||||
timeouts = Timeouts(
|
||||
callTimeoutSeconds = TANGEM_TECH_MARKETS_SERVICE_TIMEOUT_SECONDS,
|
||||
connectTimeoutSeconds = TANGEM_TECH_MARKETS_SERVICE_TIMEOUT_SECONDS,
|
||||
readTimeoutSeconds = TANGEM_TECH_MARKETS_SERVICE_TIMEOUT_SECONDS,
|
||||
),
|
||||
requestHeaders = listOf(AppVersionPlatformHeaders(appVersionProvider)),
|
||||
)
|
||||
}
|
||||
|
|
@ -133,16 +158,25 @@ class NetworkModule {
|
|||
context: Context,
|
||||
appVersionProvider: AppVersionProvider,
|
||||
baseUrl: String,
|
||||
timeoutSeconds: Long? = null,
|
||||
timeouts: Timeouts = Timeouts(),
|
||||
requestHeaders: List<RequestHeader> = listOf(CacheControlHeader, AppVersionPlatformHeaders(appVersionProvider)),
|
||||
): T {
|
||||
val client = OkHttpClient.Builder()
|
||||
.let { builder ->
|
||||
if (timeoutSeconds != null) {
|
||||
builder.callTimeout(timeoutSeconds, TimeUnit.SECONDS)
|
||||
} else {
|
||||
builder
|
||||
var b = builder
|
||||
if (timeouts.callTimeoutSeconds != null) {
|
||||
b = b.callTimeout(timeouts.callTimeoutSeconds, TimeUnit.SECONDS)
|
||||
}
|
||||
if (timeouts.connectTimeoutSeconds != null) {
|
||||
b = b.connectTimeout(timeouts.connectTimeoutSeconds, TimeUnit.SECONDS)
|
||||
}
|
||||
if (timeouts.readTimeoutSeconds != null) {
|
||||
b = b.readTimeout(timeouts.readTimeoutSeconds, TimeUnit.SECONDS)
|
||||
}
|
||||
if (timeouts.writeTimeoutSeconds != null) {
|
||||
b = b.writeTimeout(timeouts.writeTimeoutSeconds, TimeUnit.SECONDS)
|
||||
}
|
||||
b
|
||||
}
|
||||
.addHeaders(
|
||||
*requestHeaders.toTypedArray(),
|
||||
|
|
@ -161,6 +195,13 @@ class NetworkModule {
|
|||
.create(T::class.java)
|
||||
}
|
||||
|
||||
private data class Timeouts(
|
||||
val callTimeoutSeconds: Long? = null,
|
||||
val connectTimeoutSeconds: Long? = null,
|
||||
val readTimeoutSeconds: Long? = null,
|
||||
val writeTimeoutSeconds: Long? = null,
|
||||
)
|
||||
|
||||
private companion object {
|
||||
const val STAKEKIT_BASE_URL = "https://api.stakek.it/v1/"
|
||||
const val PROD_EXPRESS_BASE_URL = "https://express.tangem.com/v1/"
|
||||
|
|
@ -173,5 +214,6 @@ class NetworkModule {
|
|||
const val PROD_V2_TANGEM_TECH_BASE_URL = "https://api.tangem-tech.com/v2/"
|
||||
|
||||
const val TANGEM_TECH_SERVICE_TIMEOUT_SECONDS = 5L
|
||||
const val TANGEM_TECH_MARKETS_SERVICE_TIMEOUT_SECONDS = 60L
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package com.tangem.datasource.di
|
||||
|
||||
import com.tangem.datasource.local.datastore.RuntimeDataStore
|
||||
import com.tangem.datasource.local.token.DefaultStakingBalanceStore
|
||||
import com.tangem.datasource.local.token.StakingBalanceStore
|
||||
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 StakingBalanceStoreModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideStakingBalanceStore(): StakingBalanceStore {
|
||||
return DefaultStakingBalanceStore(dataStore = RuntimeDataStore())
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package com.tangem.datasource.di
|
||||
|
||||
import com.tangem.datasource.local.datastore.RuntimeDataStore
|
||||
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(dataStore = RuntimeDataStore())
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
package com.tangem.datasource.di
|
||||
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import com.tangem.datasource.files.FileReader
|
||||
import com.tangem.datasource.local.datastore.FileDataStore
|
||||
import com.tangem.datasource.local.token.DefaultUserTokensStore
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.datasource.local.token.AppPreferencesUserTokensStore
|
||||
import com.tangem.datasource.local.token.UserTokensStore
|
||||
import com.tangem.datasource.local.token.UserTokensStoreMigrationRunner
|
||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
|
|
@ -18,9 +18,17 @@ internal object UserTokensStoreModule {
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideUserTokensStore(fileReader: FileReader, @NetworkMoshi moshi: Moshi): UserTokensStore {
|
||||
return DefaultUserTokensStore(
|
||||
dataStore = FileDataStore(fileReader, moshi.adapter(UserTokensResponse::class.java)),
|
||||
fun provideUserTokensStore(
|
||||
appPreferencesStore: AppPreferencesStore,
|
||||
userTokensStoreMigrationRunner: UserTokensStoreMigrationRunner,
|
||||
userWalletsStore: UserWalletsStore,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
): UserTokensStore {
|
||||
return AppPreferencesUserTokensStore(
|
||||
appPreferencesStore = appPreferencesStore,
|
||||
userTokensStoreMigrationRunner = userTokensStoreMigrationRunner,
|
||||
userWalletsStore = userWalletsStore,
|
||||
dispatchers = dispatchers,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -85,6 +85,8 @@ object PreferencesKeys {
|
|||
|
||||
val IS_WALLET_NAMES_MIGRATION_DONE_KEY by lazy { booleanPreferencesKey(name = "isWalletNamesMigrationDone") }
|
||||
|
||||
val UNSUBMITTED_TRANSACTIONS_KEY by lazy { stringPreferencesKey(name = "unsubmittedTransactions") }
|
||||
|
||||
val IS_WALLET_SWAP_PROMO_OKX_SHOW_KEY by lazy {
|
||||
booleanPreferencesKey(name = "isWalletSwapPromoOkxShown")
|
||||
}
|
||||
|
|
@ -94,6 +96,22 @@ object PreferencesKeys {
|
|||
}
|
||||
|
||||
fun getStart2CoinTOSAcceptedKey(region: String?) = booleanPreferencesKey(name = "start2Coin_tos_accepted_$region")
|
||||
|
||||
// region Permission
|
||||
fun getShouldShowPermission(permission: String) = booleanPreferencesKey("shouldShowPushPermission_$permission")
|
||||
|
||||
fun getShouldShowInitialPermissionScreen(permission: String) =
|
||||
booleanPreferencesKey("shouldShowInitialPushPermissionScreen_$permission")
|
||||
|
||||
fun getIsFirstTimeAskingPermission(permission: String) =
|
||||
booleanPreferencesKey("shouldAskInitialPushPermission_$permission")
|
||||
|
||||
fun getPermissionLaunchCount(permission: String) = intPreferencesKey("pushPermissionLaunchCount_$permission")
|
||||
|
||||
fun getPermissionDaysCount(permission: String) = longPreferencesKey("pushPermissionDaysCount_$permission")
|
||||
// endregion
|
||||
|
||||
fun getUserTokensKey(userWalletId: String) = stringPreferencesKey(name = "user_tokens_$userWalletId")
|
||||
}
|
||||
|
||||
/** Preferences keys set that should be migrated from "PreferencesDataSource" to a new DataStore<Preferences> */
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import com.squareup.moshi.JsonDataException
|
|||
import com.squareup.moshi.Types
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
|
|
@ -20,7 +21,7 @@ inline fun <reified T> AppPreferencesStore.getObject(key: Preferences.Key<String
|
|||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
}.distinctUntilChanged()
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -38,7 +39,7 @@ inline fun <reified T> AppPreferencesStore.getObject(key: Preferences.Key<String
|
|||
} catch (e: JsonDataException) {
|
||||
default
|
||||
}
|
||||
}
|
||||
}.distinctUntilChanged()
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -100,7 +101,7 @@ suspend inline fun <reified T> AppPreferencesStore.storeObjectList(key: Preferen
|
|||
/** Get flow of list of data [T] by string [key]. If data is not found, it returns `null` */
|
||||
inline fun <reified T> AppPreferencesStore.getObjectList(key: Preferences.Key<String>): Flow<List<T>?> {
|
||||
val adapter = moshi.adapter<List<T>>(Types.newParameterizedType(List::class.java, T::class.java))
|
||||
return data.map { it[key]?.let(adapter::fromJson) }
|
||||
return data.map { it[key]?.let(adapter::fromJson) }.distinctUntilChanged()
|
||||
}
|
||||
|
||||
/** Get list of data [T] by string [key], or empty if data is not found */
|
||||
|
|
|
|||
|
|
@ -0,0 +1,63 @@
|
|||
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.getObject
|
||||
import com.tangem.datasource.local.preferences.utils.getObjectSyncOrNull
|
||||
import com.tangem.datasource.local.preferences.utils.storeObject
|
||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.*
|
||||
|
||||
/**
|
||||
* Implementation of [UserTokensStore] that based on [appPreferencesStore]
|
||||
*
|
||||
* @property appPreferencesStore application preference store
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal class AppPreferencesUserTokensStore(
|
||||
private val appPreferencesStore: AppPreferencesStore,
|
||||
private val userTokensStoreMigrationRunner: UserTokensStoreMigrationRunner,
|
||||
private val userWalletsStore: UserWalletsStore,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
) : UserTokensStore {
|
||||
|
||||
init {
|
||||
runUserTokensMigrations()
|
||||
}
|
||||
|
||||
override fun get(key: UserWalletId): Flow<UserTokensResponse> {
|
||||
return appPreferencesStore
|
||||
.getObject<UserTokensResponse>(PreferencesKeys.getUserTokensKey(userWalletId = key.stringValue))
|
||||
.filterNotNull()
|
||||
}
|
||||
|
||||
override suspend fun getSyncOrNull(key: UserWalletId): UserTokensResponse? {
|
||||
return appPreferencesStore.getObjectSyncOrNull(
|
||||
key = PreferencesKeys.getUserTokensKey(userWalletId = key.stringValue),
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun store(key: UserWalletId, value: UserTokensResponse) {
|
||||
appPreferencesStore.storeObject(
|
||||
key = PreferencesKeys.getUserTokensKey(userWalletId = key.stringValue),
|
||||
value = value,
|
||||
)
|
||||
}
|
||||
|
||||
// TODO: delete in 5.15 (Mobile Sprint 161) [REDACTED_JIRA]
|
||||
private fun runUserTokensMigrations() {
|
||||
userWalletsStore.userWallets
|
||||
.filter { it.isNotEmpty() }
|
||||
.take(1)
|
||||
.onEach { userWallets ->
|
||||
userTokensStoreMigrationRunner.run(ids = userWallets.map { it.walletId.stringValue })
|
||||
}
|
||||
.flowOn(dispatchers.io)
|
||||
.launchIn(CoroutineScope(dispatchers.io))
|
||||
}
|
||||
}
|
||||
|
|
@ -4,9 +4,9 @@ import com.tangem.datasource.api.express.models.response.Asset
|
|||
import com.tangem.datasource.local.datastore.core.StringKeyDataStore
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
|
||||
internal class DefaultAssetsStore(
|
||||
internal class DefaultExpressAssetsStore(
|
||||
private val dataStore: StringKeyDataStore<List<Asset>>,
|
||||
) : AssetsStore {
|
||||
) : ExpressAssetsStore {
|
||||
|
||||
override suspend fun getSyncOrNull(userWalletId: UserWalletId): List<Asset>? {
|
||||
return dataStore.getSyncOrNull(userWalletId.stringValue)
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
package com.tangem.datasource.local.token
|
||||
|
||||
import com.tangem.datasource.api.stakekit.models.response.model.BalanceDTO
|
||||
import com.tangem.datasource.api.stakekit.models.response.model.YieldBalanceWrapperDTO
|
||||
import com.tangem.datasource.local.datastore.core.StringKeyDataStore
|
||||
import com.tangem.utils.extensions.addOrReplace
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
internal class DefaultStakingBalanceStore(
|
||||
private val dataStore: StringKeyDataStore<List<YieldBalanceWrapperDTO>>,
|
||||
) : StakingBalanceStore {
|
||||
|
||||
override fun get(): Flow<List<YieldBalanceWrapperDTO>> {
|
||||
return dataStore.get(STAKING_BALANCE_KEY)
|
||||
}
|
||||
|
||||
override suspend fun getSyncOrNull(): List<YieldBalanceWrapperDTO>? {
|
||||
return dataStore.getSyncOrNull(STAKING_BALANCE_KEY)
|
||||
}
|
||||
|
||||
override suspend fun store(items: List<YieldBalanceWrapperDTO>) {
|
||||
return dataStore.store(STAKING_BALANCE_KEY, items)
|
||||
}
|
||||
|
||||
override fun get(integrationId: String): Flow<List<BalanceDTO>> {
|
||||
return dataStore.get(STAKING_BALANCE_KEY)
|
||||
.map { balances ->
|
||||
balances.filter { it.integrationId == integrationId }
|
||||
.flatMap { it.balances }
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getSyncOrNull(integrationId: String): List<BalanceDTO>? {
|
||||
return dataStore.getSyncOrNull(STAKING_BALANCE_KEY)
|
||||
?.firstOrNull { it.integrationId == integrationId }?.balances
|
||||
}
|
||||
|
||||
override suspend fun store(integrationId: String, item: YieldBalanceWrapperDTO) {
|
||||
val balances = dataStore.getSyncOrNull(STAKING_BALANCE_KEY)
|
||||
?.toMutableList()
|
||||
?.addOrReplace(item) { item.integrationId == integrationId }
|
||||
?: listOf(item)
|
||||
|
||||
return dataStore.store(STAKING_BALANCE_KEY, balances)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val STAKING_BALANCE_KEY = "STAKING_BALANCE_KEY"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package com.tangem.datasource.local.token
|
||||
|
||||
import com.tangem.datasource.local.datastore.core.StringKeyDataStore
|
||||
import com.tangem.domain.staking.model.StakingTokenWithYield
|
||||
|
||||
internal class DefaultStakingTokensStore(
|
||||
private val dataStore: StringKeyDataStore<List<StakingTokenWithYield>>,
|
||||
) : StakingTokensStore {
|
||||
|
||||
override suspend fun getSyncOrNull(): List<StakingTokenWithYield>? {
|
||||
return dataStore.getSyncOrNull(STAKING_TOKENS_KEY)
|
||||
}
|
||||
|
||||
override suspend fun store(items: List<StakingTokenWithYield>) {
|
||||
dataStore.store(STAKING_TOKENS_KEY, items)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val STAKING_TOKENS_KEY = "STAKING_TOKENS_KEY"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package com.tangem.datasource.local.token
|
||||
|
||||
import com.tangem.datasource.api.stakekit.models.response.model.YieldDTO
|
||||
import com.tangem.datasource.local.datastore.core.StringKeyDataStore
|
||||
|
||||
internal class DefaultStakingYieldsStore(
|
||||
private val dataStore: StringKeyDataStore<List<YieldDTO>>,
|
||||
) : StakingYieldsStore {
|
||||
|
||||
override suspend fun getSyncOrNull(): List<YieldDTO>? {
|
||||
return dataStore.getSyncOrNull(STAKING_YIELDS_KEY)
|
||||
}
|
||||
|
||||
override suspend fun store(items: List<YieldDTO>) {
|
||||
dataStore.store(STAKING_YIELDS_KEY, items)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val STAKING_YIELDS_KEY = "STAKING_YIELDS_KEY"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
package com.tangem.datasource.local.token
|
||||
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import com.tangem.datasource.local.datastore.core.StringKeyDataStore
|
||||
import com.tangem.datasource.local.datastore.core.StringKeyDataStoreDecorator
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
|
||||
internal class DefaultUserTokensStore(
|
||||
dataStore: StringKeyDataStore<UserTokensResponse>,
|
||||
) : UserTokensStore, StringKeyDataStoreDecorator<UserWalletId, UserTokensResponse>(dataStore) {
|
||||
|
||||
override fun provideStringKey(key: UserWalletId): String {
|
||||
return "user_tokens_${key.stringValue}"
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@ package com.tangem.datasource.local.token
|
|||
import com.tangem.datasource.api.express.models.response.Asset
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
|
||||
interface AssetsStore {
|
||||
interface ExpressAssetsStore {
|
||||
|
||||
suspend fun getSyncOrNull(userWalletId: UserWalletId): List<Asset>?
|
||||
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package com.tangem.datasource.local.token
|
||||
|
||||
import com.tangem.datasource.api.stakekit.models.response.model.BalanceDTO
|
||||
import com.tangem.datasource.api.stakekit.models.response.model.YieldBalanceWrapperDTO
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
interface StakingBalanceStore {
|
||||
|
||||
fun get(): Flow<List<YieldBalanceWrapperDTO>>
|
||||
|
||||
suspend fun getSyncOrNull(): List<YieldBalanceWrapperDTO>?
|
||||
|
||||
suspend fun store(items: List<YieldBalanceWrapperDTO>)
|
||||
|
||||
fun get(integrationId: String): Flow<List<BalanceDTO>>
|
||||
|
||||
suspend fun getSyncOrNull(integrationId: String): List<BalanceDTO>?
|
||||
|
||||
suspend fun store(integrationId: String, item: YieldBalanceWrapperDTO)
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package com.tangem.datasource.local.token
|
||||
|
||||
import com.tangem.domain.staking.model.StakingTokenWithYield
|
||||
|
||||
interface StakingTokensStore {
|
||||
|
||||
suspend fun getSyncOrNull(): List<StakingTokenWithYield>?
|
||||
|
||||
suspend fun store(items: List<StakingTokenWithYield>)
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package com.tangem.datasource.local.token
|
||||
|
||||
import com.tangem.datasource.api.stakekit.models.response.model.YieldDTO
|
||||
|
||||
interface StakingYieldsStore {
|
||||
|
||||
suspend fun getSyncOrNull(): List<YieldDTO>?
|
||||
|
||||
suspend fun store(items: List<YieldDTO>)
|
||||
}
|
||||
|
|
@ -4,11 +4,43 @@ import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
|||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Deprecated(
|
||||
message = "Use AppPreferencesStore",
|
||||
replaceWith = ReplaceWith(
|
||||
expression = "AppPreferencesStore",
|
||||
imports = arrayOf("com.tangem.datasource.local.preferences.AppPreferencesStore"),
|
||||
),
|
||||
level = DeprecationLevel.WARNING,
|
||||
)
|
||||
interface UserTokensStore {
|
||||
|
||||
@Deprecated(
|
||||
message = "Use getObject",
|
||||
replaceWith = ReplaceWith(
|
||||
expression = "appPreferencesStore.getObject(userWalletId)",
|
||||
imports = arrayOf("com.tangem.datasource.local.preferences.AppPreferencesStore"),
|
||||
),
|
||||
level = DeprecationLevel.WARNING,
|
||||
)
|
||||
fun get(key: UserWalletId): Flow<UserTokensResponse>
|
||||
|
||||
@Deprecated(
|
||||
message = "Use getObjectSyncOrNull",
|
||||
replaceWith = ReplaceWith(
|
||||
expression = "appPreferencesStore.getObjectSyncOrNull(userWalletId)",
|
||||
imports = arrayOf("com.tangem.datasource.local.preferences.AppPreferencesStore"),
|
||||
),
|
||||
level = DeprecationLevel.WARNING,
|
||||
)
|
||||
suspend fun getSyncOrNull(key: UserWalletId): UserTokensResponse?
|
||||
|
||||
@Deprecated(
|
||||
message = "Use storeObject",
|
||||
replaceWith = ReplaceWith(
|
||||
expression = "appPreferencesStore.storeObject(userWalletId, response)",
|
||||
imports = arrayOf("com.tangem.datasource.local.preferences.AppPreferencesStore"),
|
||||
),
|
||||
level = DeprecationLevel.WARNING,
|
||||
)
|
||||
suspend fun store(key: UserWalletId, value: UserTokensResponse)
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
package com.tangem.datasource.local.token
|
||||
|
||||
import androidx.datastore.core.DataMigration
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.squareup.moshi.adapter
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import com.tangem.datasource.files.FileReader
|
||||
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.datasource.local.preferences.utils.storeObject
|
||||
|
||||
/**
|
||||
* Migration of saving [UserTokensResponse] from file to [AppPreferencesStore]
|
||||
*
|
||||
* @param userWalletId user wallet id
|
||||
* @param moshi moshi
|
||||
* @property fileReader file reader
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal class UserTokensStoreMigration(
|
||||
userWalletId: String,
|
||||
moshi: Moshi,
|
||||
private val fileReader: FileReader,
|
||||
) : DataMigration<AppPreferencesStore> {
|
||||
|
||||
private val legacyFileName = "user_tokens_$userWalletId"
|
||||
private val keyName = PreferencesKeys.getUserTokensKey(userWalletId = userWalletId)
|
||||
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
private val adapter = moshi.adapter<UserTokensResponse>()
|
||||
|
||||
override suspend fun shouldMigrate(currentData: AppPreferencesStore): Boolean = true
|
||||
|
||||
override suspend fun migrate(currentData: AppPreferencesStore): AppPreferencesStore {
|
||||
val currentKey = currentData.getObjectSyncOrNull<UserTokensResponse>(key = keyName)
|
||||
|
||||
if (currentKey != null) return currentData
|
||||
|
||||
val value = runCatching {
|
||||
val json = fileReader.readFile(legacyFileName)
|
||||
adapter.fromJson(json)
|
||||
}.getOrNull()
|
||||
|
||||
if (value != null) {
|
||||
currentData.storeObject(key = keyName, value = value)
|
||||
}
|
||||
|
||||
return currentData
|
||||
}
|
||||
|
||||
override suspend fun cleanUp() {
|
||||
fileReader.removeFile(legacyFileName)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
package com.tangem.datasource.local.token
|
||||
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.tangem.datasource.di.NetworkMoshi
|
||||
import com.tangem.datasource.files.FileReader
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.withContext
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
/**
|
||||
* Runner that launch migrations of saving user tokens store
|
||||
*
|
||||
* @property appPreferencesStore application preference store
|
||||
* @property fileReader file reader
|
||||
* @property moshi moshi
|
||||
* @property dispatchers dispatchers
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@Singleton
|
||||
class UserTokensStoreMigrationRunner @Inject constructor(
|
||||
private val appPreferencesStore: AppPreferencesStore,
|
||||
private val fileReader: FileReader,
|
||||
@NetworkMoshi private val moshi: Moshi,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
) {
|
||||
|
||||
suspend fun run(ids: List<String>) {
|
||||
ids.forEach { id ->
|
||||
coroutineScope { run(id) }
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun run(id: String) {
|
||||
withContext(dispatchers.io) {
|
||||
val migration = UserTokensStoreMigration(
|
||||
userWalletId = id,
|
||||
moshi = moshi,
|
||||
fileReader = fileReader,
|
||||
)
|
||||
|
||||
migration.migrate(appPreferencesStore)
|
||||
|
||||
migration.cleanUp()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,11 +2,14 @@ package com.tangem.datasource.local.userwallet
|
|||
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
interface UserWalletsStore {
|
||||
|
||||
val selectedUserWalletOrNull: UserWallet?
|
||||
|
||||
val userWallets: Flow<List<UserWallet>>
|
||||
|
||||
suspend fun getSyncOrNull(key: UserWalletId): UserWallet?
|
||||
|
||||
suspend fun getAllSyncOrNull(): List<UserWallet>?
|
||||
|
|
|
|||
|
|
@ -35,5 +35,6 @@ sealed class RequestHeader(vararg pairs: Pair<String, () -> String>) {
|
|||
|
||||
class StakeKit(stakeKitAuthProvider: StakeKitAuthProvider) : RequestHeader(
|
||||
"X-API-KEY" to { stakeKitAuthProvider.getApiKey() },
|
||||
"accept" to { "application/json" },
|
||||
)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue