Updated on 2026-08-14

This commit is contained in:
Tangem 2025-08-04 20:09:55 +03:00
commit a33afd3583
684 changed files with 8006 additions and 4239 deletions

View file

@ -5,7 +5,7 @@ import com.squareup.moshi.JsonClass
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
import com.tangem.domain.staking.model.stakekit.action.StakingActionType
import com.tangem.domain.models.staking.action.StakingActionType
@JsonClass(generateAdapter = true)
data class PendingActionRequestBody(

View file

@ -0,0 +1,34 @@
package com.tangem.datasource.di
import com.tangem.datasource.local.datastore.RuntimeDataStore
import com.tangem.datasource.local.datastore.RuntimeSharedStore
import com.tangem.datasource.local.swap.DefaultSwapBestRateAnimationStore
import com.tangem.datasource.local.swap.DefaultSwapTransactionStatusStore
import com.tangem.datasource.local.swap.SwapBestRateAnimationStore
import com.tangem.datasource.local.swap.SwapTransactionStatusStore
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
object SwapStoreModule {
@Provides
@Singleton
fun provideSwapTransactionStatusStore(): SwapTransactionStatusStore {
return DefaultSwapTransactionStatusStore(
dataStore = RuntimeDataStore(),
)
}
@Provides
@Singleton
fun provideSwapBestRateAnimationStore(): SwapBestRateAnimationStore {
return DefaultSwapBestRateAnimationStore(
dataStore = RuntimeSharedStore(),
)
}
}

View file

@ -1,23 +0,0 @@
package com.tangem.datasource.di
import com.tangem.datasource.local.datastore.RuntimeDataStore
import com.tangem.datasource.local.swaptx.DefaultSwapTransactionStatusStore
import com.tangem.datasource.local.swaptx.SwapTransactionStatusStore
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
object SwapTransactionStatusStoreModule {
@Provides
@Singleton
fun provideSwapTransactionStatusStore(): SwapTransactionStatusStore {
return DefaultSwapTransactionStatusStore(
dataStore = RuntimeDataStore(),
)
}
}

View file

@ -149,6 +149,8 @@ object PreferencesKeys {
val TRON_NETWORK_FEE_NOTIFICATION_SHOW_COUNT_KEY by lazy {
intPreferencesKey(name = "tronNetworkFeeNotificationShowCount")
}
fun getShouldShowNotificationKey(key: String) = booleanPreferencesKey("showShowNotificationUM_$key")
// endregion
// region Promo

View file

@ -0,0 +1,21 @@
package com.tangem.datasource.local.swap
import com.tangem.datasource.local.datastore.RuntimeSharedStore
internal class DefaultSwapBestRateAnimationStore(
private val dataStore: RuntimeSharedStore<Boolean>,
) : SwapBestRateAnimationStore, RuntimeSharedStore<Boolean> by dataStore {
/**
* Returns flag indicating whether should show best rate animation in current session.
* Animation should appear once per session
*
* If true, reset flag to false
*/
override suspend fun getSyncOrNull(): Boolean {
val value = dataStore.getSyncOrNull() ?: true
if (value) {
dataStore.store(false)
}
return value
}
}

View file

@ -1,4 +1,4 @@
package com.tangem.datasource.local.swaptx
package com.tangem.datasource.local.swap
import com.tangem.datasource.local.datastore.core.StringKeyDataStore

View file

@ -0,0 +1,11 @@
package com.tangem.datasource.local.swap
/**
* Stores flag indicating whether should show best rate animation in current session.
* Animation should appear once per session
*
* If true, reset flag to false
*/
interface SwapBestRateAnimationStore {
suspend fun getSyncOrNull(): Boolean
}

View file

@ -1,4 +1,4 @@
package com.tangem.datasource.local.swaptx
package com.tangem.datasource.local.swap
/**
* Runtime cache for storing swap transactions statuses sent to analytics

View file

@ -1,7 +1,7 @@
package com.tangem.datasource.local.token.converter
import com.tangem.datasource.api.stakekit.models.response.model.BalanceDTO.BalanceTypeDTO
import com.tangem.domain.staking.model.stakekit.BalanceType
import com.tangem.domain.models.staking.BalanceType
import com.tangem.utils.converter.Converter
internal object BalanceTypeConverter : Converter<BalanceTypeDTO, BalanceType> {

View file

@ -1,8 +1,8 @@
package com.tangem.datasource.local.token.converter
import com.tangem.datasource.api.stakekit.models.response.model.BalanceDTO
import com.tangem.domain.staking.model.stakekit.PendingAction
import com.tangem.domain.staking.model.stakekit.PendingActionConstraints
import com.tangem.domain.models.staking.PendingAction
import com.tangem.domain.models.staking.PendingActionConstraints
import com.tangem.utils.converter.Converter
internal object PendingActionConstraintsConverter :

View file

@ -1,7 +1,7 @@
package com.tangem.datasource.local.token.converter
import com.tangem.datasource.api.stakekit.models.response.model.BalanceDTO
import com.tangem.domain.staking.model.stakekit.PendingAction
import com.tangem.domain.models.staking.PendingAction
import com.tangem.utils.converter.Converter
internal object PendingActionConverter : Converter<BalanceDTO.PendingAction, PendingAction> {

View file

@ -1,7 +1,7 @@
package com.tangem.datasource.local.token.converter
import com.tangem.datasource.api.stakekit.models.response.model.action.StakingActionTypeDTO
import com.tangem.domain.staking.model.stakekit.action.StakingActionType
import com.tangem.domain.models.staking.action.StakingActionType
import com.tangem.utils.converter.Converter
@Suppress("CyclomaticComplexMethod")

View file

@ -1,7 +1,7 @@
package com.tangem.datasource.local.token.converter
import com.tangem.datasource.api.stakekit.models.response.model.NetworkTypeDTO
import com.tangem.domain.staking.model.stakekit.NetworkType
import com.tangem.domain.models.staking.NetworkType
import com.tangem.utils.converter.TwoWayConverter
@Suppress("CyclomaticComplexMethod", "LongMethod")

View file

@ -1,53 +1,61 @@
package com.tangem.datasource.local.token.converter
import com.tangem.datasource.api.stakekit.models.response.model.BalanceDTO
import com.tangem.datasource.api.stakekit.models.response.model.YieldBalanceWrapperDTO
import com.tangem.domain.models.StatusSource
import com.tangem.domain.staking.model.stakekit.BalanceItem
import com.tangem.domain.staking.model.stakekit.YieldBalance
import com.tangem.domain.staking.model.stakekit.YieldBalanceItem
import com.tangem.domain.models.staking.BalanceItem
import com.tangem.domain.models.staking.StakingID
import com.tangem.domain.models.staking.YieldBalance
import com.tangem.domain.models.staking.YieldBalanceItem
import com.tangem.utils.converter.Converter
import kotlinx.datetime.Instant
class YieldBalanceConverter(
private val source: StatusSource,
) : Converter<YieldBalanceWrapperDTO, YieldBalance> {
) : Converter<YieldBalanceWrapperDTO, YieldBalance?> {
constructor(isCached: Boolean) : this(source = if (isCached) StatusSource.CACHE else StatusSource.ACTUAL)
override fun convert(value: YieldBalanceWrapperDTO): YieldBalance {
override fun convert(value: YieldBalanceWrapperDTO): YieldBalance? {
val stakingId = StakingID(
integrationId = value.integrationId ?: return null,
address = value.addresses.address,
)
return if (value.balances.isEmpty()) {
YieldBalance.Empty(
integrationId = value.integrationId,
address = value.addresses.address,
source = source,
)
YieldBalance.Empty(stakingId = stakingId, source = source)
} else {
YieldBalance.Data(
integrationId = value.integrationId,
address = value.addresses.address,
stakingId = stakingId,
balance = YieldBalanceItem(
items = value.balances.map { item ->
BalanceItem(
groupId = item.groupId,
token = TokenConverter.convert(item.tokenDTO),
type = BalanceTypeConverter.convert(item.type),
amount = item.amount,
rawCurrencyId = item.tokenDTO.coinGeckoId,
// tron-specific. operates validatorAddresses instead of validatorAddress
validatorAddress = item.validatorAddress ?: item.validatorAddresses?.get(0),
date = item.date?.toDateTime(),
pendingActions = PendingActionConverter
.convertList(item.pendingActions)
.sortedBy { it.passthrough },
pendingActionsConstraints = PendingActionConstraintsConverter
.convertList(item.pendingActionConstraints.orEmpty()),
isPending = false,
)
}
.sortedWith(compareBy({ it.type }, { it.amount })),
items = value.balances
.map { item -> item.toBalanceItem() }
.sortedWith(comparator = compareBy({ it.type }, { it.amount })),
integrationId = value.integrationId,
),
source = source,
)
}
}
private fun BalanceDTO.toBalanceItem(): BalanceItem {
val item = this
return BalanceItem(
groupId = item.groupId,
token = YieldTokenConverter.convert(item.tokenDTO),
type = BalanceTypeConverter.convert(item.type),
amount = item.amount,
rawCurrencyId = item.tokenDTO.coinGeckoId,
// tron-specific. operates validatorAddresses instead of validatorAddress
validatorAddress = item.validatorAddress ?: item.validatorAddresses?.get(0),
date = item.date?.toString()?.let { Instant.parse(it) },
pendingActions = PendingActionConverter
.convertList(item.pendingActions)
.sortedBy { it.passthrough },
pendingActionsConstraints = PendingActionConstraintsConverter
.convertList(item.pendingActionConstraints.orEmpty()),
isPending = false,
)
}
}

View file

@ -1,13 +1,13 @@
package com.tangem.datasource.local.token.converter
import com.tangem.datasource.api.stakekit.models.response.model.TokenDTO
import com.tangem.domain.staking.model.stakekit.Token
import com.tangem.domain.models.staking.YieldToken
import com.tangem.utils.converter.TwoWayConverter
object TokenConverter : TwoWayConverter<TokenDTO, Token> {
object YieldTokenConverter : TwoWayConverter<TokenDTO, YieldToken> {
override fun convert(value: TokenDTO): Token {
return Token(
override fun convert(value: TokenDTO): YieldToken {
return YieldToken(
name = value.name,
network = StakingNetworkTypeConverter.convert(value.network),
symbol = value.symbol,
@ -19,7 +19,7 @@ object TokenConverter : TwoWayConverter<TokenDTO, Token> {
)
}
override fun convertBack(value: Token): TokenDTO {
override fun convertBack(value: YieldToken): TokenDTO {
return TokenDTO(
name = value.name,
network = StakingNetworkTypeConverter.convertBack(value.network),