diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/stakekit/StakeKitApi.kt b/core/datasource/src/main/java/com/tangem/datasource/api/stakekit/StakeKitApi.kt index d6519755c5..b6304ee6a3 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/api/stakekit/StakeKitApi.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/api/stakekit/StakeKitApi.kt @@ -19,6 +19,7 @@ interface StakeKitApi { @Query("preferredValidatorsOnly") preferredValidatorsOnly: Boolean? = null, @Query("ledgerWalletAPICompatible") ledgerWalletAPICompatible: Boolean? = null, @Query("type") type: YieldType? = null, + @Query("yieldId") yieldId: String? = null, @Query("revenueOption") revenueOption: RevenueOption? = null, @Query("page") page: Int? = null, @Query("network") network: String? = null, diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/token/DefaultStakingYieldsStore.kt b/core/datasource/src/main/java/com/tangem/datasource/local/token/DefaultStakingYieldsStore.kt index 73800ea6dd..cdac7d46bf 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/local/token/DefaultStakingYieldsStore.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/local/token/DefaultStakingYieldsStore.kt @@ -24,8 +24,19 @@ internal class DefaultStakingYieldsStore( } override suspend fun store(items: List) { - dataStore.updateData { _ -> - items + dataStore.updateData { data -> + val updatedItems = data.toMutableList() + items.forEach { newItem -> + val existingItemIndex = data.indexOfFirst { it.id == newItem.id } + if (existingItemIndex != -1) { + // Update existing item + updatedItems[existingItemIndex] = newItem + } else { + // Add new item + updatedItems.add(newItem) + } + } + updatedItems } } diff --git a/data/staking/src/main/java/com/tangem/data/staking/DefaultStakingRepository.kt b/data/staking/src/main/java/com/tangem/data/staking/DefaultStakingRepository.kt index 5230a94938..e279943212 100644 --- a/data/staking/src/main/java/com/tangem/data/staking/DefaultStakingRepository.kt +++ b/data/staking/src/main/java/com/tangem/data/staking/DefaultStakingRepository.kt @@ -24,6 +24,7 @@ import com.tangem.datasource.api.common.response.ApiResponse import com.tangem.datasource.api.common.response.getOrThrow import com.tangem.datasource.api.stakekit.StakeKitApi 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.NetworkTypeDTO import com.tangem.datasource.api.stakekit.models.response.model.action.StakingActionStatusDTO import com.tangem.datasource.api.stakekit.models.response.model.transaction.tron.TronStakeKitTransaction @@ -56,6 +57,8 @@ import com.tangem.lib.crypto.BlockchainUtils.isCardano import com.tangem.lib.crypto.BlockchainUtils.isSolana import com.tangem.utils.coroutines.CoroutineDispatcherProvider import com.tangem.utils.extensions.orZero +import kotlinx.coroutines.async +import kotlinx.coroutines.awaitAll import kotlinx.coroutines.flow.* import kotlinx.coroutines.withContext import timber.log.Timber @@ -91,17 +94,20 @@ internal class DefaultStakingRepository( override suspend fun fetchEnabledYields() { withContext(dispatchers.io) { - when (val stakingTokensWithYields = stakeKitApi.getEnabledYields(preferredValidatorsOnly = false)) { - is ApiResponse.Success -> stakingYieldsStore.store( - stakingTokensWithYields.data.data.filter { - it.isAvailable == true - }, - ) - else -> { - stakingYieldsStore.store(emptyList()) - throw (stakingTokensWithYields as ApiResponse.Error).cause + val yieldsResponses = getAvailableIntegrationsIds().map { + async { it.getYieldRequest() } + }.awaitAll() + + val yields = yieldsResponses.flatMap { response -> + when (response) { + is ApiResponse.Success -> response.data.data.filter { yield -> yield.isAvailable == true } + else -> { + Timber.e("Error fetching enabled yields: ${(response as? ApiResponse.Error)?.cause}") + emptyList() + } } } + stakingYieldsStore.store(yields) } } @@ -151,6 +157,26 @@ internal class DefaultStakingRepository( } } + private suspend fun StakingIntegrationID.getYieldRequest(): ApiResponse { + return when (this) { + is StakingIntegrationID.Coin -> stakeKitApi.getEnabledYields( + preferredValidatorsOnly = false, + network = networkId, + ) + is StakingIntegrationID.EthereumToken -> stakeKitApi.getEnabledYields( + preferredValidatorsOnly = false, + yieldId = value, + network = networkId, + ) + } + } + + private fun getAvailableIntegrationsIds(): List { + return StakingIntegrationID.entries.filterNot { + it.blockchain == Blockchain.Cardano && !stakingFeatureToggles.isCardanoStakingEnabled + } + } + private fun NetworkTypeDTO.extractJsonName(): String { return networkTypeAdapter.toJson(this).replace("\"", "") } @@ -364,7 +390,8 @@ internal class DefaultStakingRepository( ) val transaction = transactionConverter.convert(transactionResponse.getOrThrow()) - val unsignedTransaction = transaction.unsignedTransaction ?: error("No unsigned transaction available") + val unsignedTransaction = + transaction.unsignedTransaction ?: error("No unsigned transaction available") val transactionData = TransactionData.Compiled( value = getTransactionDataType(networkId, unsignedTransaction), fee = fee, diff --git a/domain/staking/src/main/java/com/tangem/domain/staking/model/StakingIntegrationID.kt b/domain/staking/src/main/java/com/tangem/domain/staking/model/StakingIntegrationID.kt index f1514e69a5..ff38b75b71 100644 --- a/domain/staking/src/main/java/com/tangem/domain/staking/model/StakingIntegrationID.kt +++ b/domain/staking/src/main/java/com/tangem/domain/staking/model/StakingIntegrationID.kt @@ -23,31 +23,43 @@ sealed interface StakingIntegrationID { /** Approval requirements for the staking integration. Defaults to no approval needed */ val approval: StakingApproval get() = StakingApproval.Empty + /** + * Represents the network ID associated with the staking integration from provider + * https://docs.yield.xyz/reference/yieldscontroller_getyields + */ + val networkId: String + /** Represents blockchains whose native coins can be staked */ enum class Coin : StakingIntegrationID { Ton { override val value: String = "ton-ton-chorus-one-pools-staking" override val blockchain: Blockchain = Blockchain.TON + override val networkId: String = "ton" }, Solana { override val value: String = "solana-sol-native-multivalidator-staking" override val blockchain: Blockchain = Blockchain.Solana + override val networkId: String = "solana" }, Cosmos { override val value: String = "cosmos-atom-native-staking" override val blockchain: Blockchain = Blockchain.Cosmos + override val networkId: String = "cosmos" }, Tron { override val value: String = "tron-trx-native-staking" override val blockchain: Blockchain = Blockchain.Tron + override val networkId: String = "tron" }, BSC { override val value: String = "bsc-bnb-native-staking" override val blockchain: Blockchain = Blockchain.BSC + override val networkId: String = "binance" }, Cardano { override val value: String = "cardano-ada-native-staking" override val blockchain: Blockchain = Blockchain.Cardano + override val networkId: String = "cardano" }, } @@ -61,6 +73,7 @@ sealed interface StakingIntegrationID { override val value: String = "ethereum-matic-native-staking" override val approval: StakingApproval.Needed = StakingApproval.Needed(spenderAddress = "0x5e3Ef299fDDf15eAa0432E6e66473ace8c13D908") + override val networkId: String = "ethereum" }, ; diff --git a/tangem-android-tools b/tangem-android-tools index baaed0af71..b64f8659fc 160000 --- a/tangem-android-tools +++ b/tangem-android-tools @@ -1 +1 @@ -Subproject commit baaed0af71b07b226796a023bf4ac2ea410918e2 +Subproject commit b64f8659fce65e7749d50923b32bfad13e6b8cac