Updated on 2026-08-14

This commit is contained in:
Tangem 2024-09-02 13:28:13 +05:00
parent 47e284436a
commit 0387fb8a4f
10 changed files with 33 additions and 57 deletions

View file

@ -2,12 +2,15 @@ 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.request.Address
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 = "addresses")
val addresses: Address,
@Json(name = "balances")
val balances: List<BalanceDTO>,
@Json(name = "integrationId")

View file

@ -1,12 +1,11 @@
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.domain.wallets.models.UserWalletId
import com.tangem.utils.extensions.addOrReplace
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
@ -30,17 +29,16 @@ internal class DefaultStakingBalanceStore(
}
}
override fun get(userWalletId: UserWalletId, integrationId: String): Flow<List<BalanceDTO>> {
override fun get(userWalletId: UserWalletId, integrationId: String): Flow<YieldBalanceWrapperDTO> {
return dataStore.get(userWalletId.stringValue)
.map { balances ->
balances.filter { it.integrationId == integrationId }
.flatMap { it.balances }
.mapNotNull { balances ->
balances.firstOrNull { it.integrationId == integrationId }
}
}
override suspend fun getSyncOrNull(userWalletId: UserWalletId, integrationId: String): List<BalanceDTO>? {
override suspend fun getSyncOrNull(userWalletId: UserWalletId, integrationId: String): YieldBalanceWrapperDTO? {
return dataStore.getSyncOrNull(userWalletId.stringValue)
?.firstOrNull { it.integrationId == integrationId }?.balances
?.firstOrNull { it.integrationId == integrationId }
}
override suspend fun store(userWalletId: UserWalletId, integrationId: String, item: YieldBalanceWrapperDTO) {

View file

@ -1,6 +1,5 @@
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.domain.wallets.models.UserWalletId
import kotlinx.coroutines.flow.Flow
@ -13,9 +12,9 @@ interface StakingBalanceStore {
suspend fun store(userWalletId: UserWalletId, items: Set<YieldBalanceWrapperDTO>)
fun get(userWalletId: UserWalletId, integrationId: String): Flow<List<BalanceDTO>>
fun get(userWalletId: UserWalletId, integrationId: String): Flow<YieldBalanceWrapperDTO>
suspend fun getSyncOrNull(userWalletId: UserWalletId, integrationId: String): List<BalanceDTO>?
suspend fun getSyncOrNull(userWalletId: UserWalletId, integrationId: String): YieldBalanceWrapperDTO?
suspend fun store(userWalletId: UserWalletId, integrationId: String, item: YieldBalanceWrapperDTO)
}

View file

@ -299,6 +299,7 @@ internal class DefaultStakingRepository(
YieldBalanceWrapperDTO(
balances = result,
integrationId = requestBody.integrationId,
addresses = requestBody.addresses,
),
)
},
@ -317,14 +318,7 @@ internal class DefaultStakingRepository(
?: error("Could not get integrationId")
stakingBalanceStore.get(userWalletId, integrationId)
.collectLatest {
send(
yieldBalanceConverter.convert(
YieldBalanceConverter.Data(
balance = it,
integrationId = integrationId,
),
),
)
send(yieldBalanceConverter.convert(it))
}
}
@ -351,12 +345,7 @@ internal class DefaultStakingRepository(
val result = stakingBalanceStore.getSyncOrNull(userWalletId, integrationId)
?: return@withContext YieldBalance.Error
yieldBalanceConverter.convert(
YieldBalanceConverter.Data(
balance = result,
integrationId = integrationId,
),
)
yieldBalanceConverter.convert(result)
}
}
@ -385,7 +374,7 @@ internal class DefaultStakingRepository(
null
}
}
.distinct()
.distinctBy { it.second }
.map { getBalanceRequestData(it.first, it.second) }
.ifEmpty { return@invokeOnExpire }
val result = stakeKitApi.getMultipleYieldBalances(availableCurrencies).getOrThrow()

View file

@ -1,24 +1,22 @@
package com.tangem.data.staking.converters
import com.tangem.data.staking.converters.action.PendingActionConverter
import com.tangem.datasource.api.stakekit.models.response.model.BalanceDTO
import com.tangem.domain.staking.model.stakekit.BalanceItem
import com.tangem.domain.staking.model.stakekit.BalanceType
import com.tangem.domain.staking.model.stakekit.YieldBalance
import com.tangem.domain.staking.model.stakekit.YieldBalanceItem
import com.tangem.datasource.api.stakekit.models.response.model.YieldBalanceWrapperDTO
import com.tangem.domain.staking.model.stakekit.*
import com.tangem.utils.converter.Converter
internal class YieldBalanceConverter : Converter<YieldBalanceConverter.Data, YieldBalance> {
internal class YieldBalanceConverter : Converter<YieldBalanceWrapperDTO, YieldBalance> {
private val pendingActionConverter by lazy(LazyThreadSafetyMode.NONE) { PendingActionConverter() }
override fun convert(value: Data): YieldBalance {
return if (value.balance.isEmpty()) {
override fun convert(value: YieldBalanceWrapperDTO): YieldBalance {
return if (value.balances.isEmpty()) {
YieldBalance.Empty
} else {
YieldBalance.Data(
address = value.addresses.address,
balance = YieldBalanceItem(
items = value.balance.map { item ->
items = value.balances.map { item ->
BalanceItem(
type = BalanceType.valueOf(item.type.name),
amount = item.amount,
@ -35,9 +33,4 @@ internal class YieldBalanceConverter : Converter<YieldBalanceConverter.Data, Yie
)
}
}
data class Data(
val balance: List<BalanceDTO>,
val integrationId: String?,
)
}

View file

@ -15,14 +15,7 @@ internal class YieldBalanceListConverter : Converter<Set<YieldBalanceWrapperDTO>
YieldBalanceList.Empty
} else {
YieldBalanceList.Data(
balances = value.map {
converter.convert(
YieldBalanceConverter.Data(
balance = it.balances,
integrationId = it.integrationId,
),
)
},
balances = value.map(converter::convert),
)
}
}

View file

@ -8,6 +8,7 @@ sealed class YieldBalance {
data class Data(
val balance: YieldBalanceItem,
val address: String,
) : YieldBalance() {
fun getTotalStakingBalance(): BigDecimal {
return balance.items

View file

@ -57,14 +57,16 @@ internal class CurrencyStatusOperations(
val hasCurrentNetworkTransactions = status.pendingTransactions.isNotEmpty()
val currentTransactions = status.pendingTransactions.getOrElse(currency.id, ::emptySet)
val isCurrentAddressStaking =
(yieldBalance as? YieldBalance.Data)?.address == status.address.defaultAddress.value
val currentYieldBalance = yieldBalance.takeIf { isCurrentAddressStaking }
return when {
ignoreQuote -> CryptoCurrencyStatus.NoQuote(
amount = amount,
hasCurrentNetworkTransactions = hasCurrentNetworkTransactions,
pendingTransactions = currentTransactions,
networkAddress = status.address,
yieldBalance = yieldBalance,
yieldBalance = currentYieldBalance,
)
currency is CryptoCurrency.Token && currency.isCustom -> CryptoCurrencyStatus.Custom(
amount = amount,
@ -74,7 +76,7 @@ internal class CurrencyStatusOperations(
hasCurrentNetworkTransactions = hasCurrentNetworkTransactions,
pendingTransactions = currentTransactions,
networkAddress = status.address,
yieldBalance = yieldBalance,
yieldBalance = currentYieldBalance,
)
quote == null -> CryptoCurrencyStatus.Loading
else -> CryptoCurrencyStatus.Loaded(
@ -85,7 +87,7 @@ internal class CurrencyStatusOperations(
hasCurrentNetworkTransactions = hasCurrentNetworkTransactions,
pendingTransactions = currentTransactions,
networkAddress = status.address,
yieldBalance = yieldBalance,
yieldBalance = currentYieldBalance,
)
}
}

View file

@ -4,7 +4,6 @@ import arrow.core.Either
import arrow.core.left
import arrow.core.right
import com.tangem.domain.core.error.DataError
import com.tangem.domain.staking.model.stakekit.YieldBalance
import com.tangem.domain.tokens.error.CurrencyStatusError
import com.tangem.domain.tokens.mock.MockNetworks
import com.tangem.domain.tokens.mock.MockQuotes
@ -123,7 +122,7 @@ internal class GetPrimaryCurrencyStatusUpdatesUseCaseTest {
networkAddress = NetworkAddress.Single(
defaultAddress = NetworkAddress.Address(value = "mock", NetworkAddress.Address.Type.Primary),
),
yieldBalance = YieldBalance.Error,
yieldBalance = null,
),
)
}

View file

@ -1,7 +1,6 @@
package com.tangem.domain.tokens.mock
import arrow.core.nonEmptyListOf
import com.tangem.domain.staking.model.stakekit.YieldBalance
import com.tangem.domain.tokens.model.CryptoCurrencyAmountStatus
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.tokens.model.NetworkAddress
@ -152,7 +151,7 @@ internal object MockTokensStates {
pendingTransactions = emptySet(),
hasCurrentNetworkTransactions = false,
networkAddress = requireNotNull(networkStatus.value as? NetworkStatus.Verified).address,
yieldBalance = YieldBalance.Error,
yieldBalance = null,
),
)
}
@ -168,7 +167,7 @@ internal object MockTokensStates {
.first { it.network == status.currency.network }
.value as? NetworkStatus.Verified,
).address,
yieldBalance = YieldBalance.Error,
yieldBalance = null,
),
)
}