diff --git a/core/res/src/main/res/values-de/strings.xml b/core/res/src/main/res/values-de/strings.xml
index ef2d858a71..c130e68816 100644
--- a/core/res/src/main/res/values-de/strings.xml
+++ b/core/res/src/main/res/values-de/strings.xml
@@ -650,6 +650,8 @@
Die Anzahl der zu stakenden Krypros muss mindesten %s betragen
Der Stakingbetrag wird aufgrund der Netzwerkregeln auf %1$s TRX aufgerundet.
Nicht gestakte beanspruche
+ Gebühr für das Staking-Konto
+ Ein Staking-Konto ist ein spezielles Konto, auf dem eingesetzte SOL-Token gelagert werden. Es wird erstellt, wenn du deine Token an einen Validator delegierst, um an der Transaktionsvalidierung teilzunehmen und Belohnungen zu verdienen. Für die Erstellung des Staking-Kontos wird eine geringe Gebühr erhoben, die nach Abschluss des Stakings zurückgegeben wird.
Jährliche prozentuale Rendite
Die jährliche prozentuale Rendite, die du durch die Teilnahme am Staking erzielen kannst.
Effektiver Jahreszins
@@ -705,6 +707,7 @@
Block
Tag
Täglich
+ Jeder %1$s
Epoche
Ära
Stunde
@@ -721,6 +724,7 @@
Die Transaktion wird bearbeitet! Derzeit findet eine Validierung in der Blockchain statt. Dies kann einige Minuten dauern.
Lösen der Bindungen
Gelocktes unlocken
+ Entsperren
Unstaken
Staking beenden
Unstake Assets %s
@@ -863,6 +867,8 @@
Aktivierungsfehler
Laut den Entwicklern des BNB-Netzes wird die Unterstützung für den BEP-2-Standard im Juni 2024 enden. Um den Verlust von Vermögenswerten mit diesem Standard zu vermeiden, konvertiere bitte in den BEP-20 Standard. Nutze gerne unseren Swap-Service, um sie auf das BNB Smart Chain Netzwerk zu übertragen.
BNB Beacon Chain wird abgeschaltet
+ Bitte zahle ein paar %1$s ein, um die Netzwerkgebühr zu decken
+ Unzureichende Mittel zur Deckung der Netzgebühr
Ausbaufähig
Gefällt mir
OK, habe ich verstanden!
diff --git a/core/res/src/main/res/values-ja/strings.xml b/core/res/src/main/res/values-ja/strings.xml
index ace34d86b3..1a848e9582 100644
--- a/core/res/src/main/res/values-ja/strings.xml
+++ b/core/res/src/main/res/values-ja/strings.xml
@@ -640,6 +640,8 @@
ステーキング金額は %s 以上である必要があります
ネットワークルールにより、ステーキング金額は%1$s TRX に切り上げられます。
ステーキング解除分を請求する
+ ステーキングアカウント手数料
+ ステーキングアカウントは、ステーキングされたSOLトークンが保管される特別なアカウントです。取引の検証に参加して報酬を得るために、トークンをバリデーターに委任すると、このアカウントが作成されます。ステーキングアカウントの作成には少額の手数料がかかりますが、この手数料はステーキングが完了すると返金されます。
年率
ステーキングに参加することで得られる年間収益率。
APR
@@ -695,6 +697,7 @@
ブロック
日
毎日
+ %1$s毎
エポック
時代
時
@@ -711,6 +714,7 @@
取引を処理中です。現在、ブロックチェーンで検証が行われています。これには数分かかる場合があります。
ステーキング解約中
ロック解除
+ ロック解除中
ステーキングされていない
ステーキング解除
ステーキング解除中の資産%s
diff --git a/core/res/src/main/res/values-ru/strings.xml b/core/res/src/main/res/values-ru/strings.xml
index fff0190f6d..6ffdadf52b 100644
--- a/core/res/src/main/res/values-ru/strings.xml
+++ b/core/res/src/main/res/values-ru/strings.xml
@@ -654,6 +654,7 @@
Имя
Сумма для стейкинга должна быть не менее %s
Забрать средства
+ Стейкинг аккаунт — это специальный счет, на котором хранятся застейканные токены SOL. Он создается при делегировании ваших токенов валидатору для участия в подтверждении транзакций и получении наград. За создание стейкинг аккаунта взимается небольшая комиссия, которая возвращается после завершения стейкинга.
Процентная ставка
Годовой процентный доход, который вы можете получить от участия в стейкинге.
APR
@@ -697,6 +698,7 @@
Блок
День
Каждый день
+ Каждые ~%1$s сек
Эпоха
Эра
Час
diff --git a/core/res/src/main/res/values-uk-rUA/strings.xml b/core/res/src/main/res/values-uk-rUA/strings.xml
index 9ef0e3fb24..9e4b55bc64 100644
--- a/core/res/src/main/res/values-uk-rUA/strings.xml
+++ b/core/res/src/main/res/values-uk-rUA/strings.xml
@@ -120,7 +120,7 @@
Перейти до провайдера
Перейти до токену
Імпортувати
- процесі
+ В процесі
Пізніше
Залишилося %1$s
Заблокований
@@ -357,6 +357,7 @@
Моє портфоліо
Маркет
Щоб згенерувати адреси для обраних мереж, потрібно відсканувати свою картку Tangem
+ Щоб додати токени, потягніть вгору або торкніться панелі пошуку
Дані цього розділу отримані з наступних мереж: %s
Не вдалося завантажити дані...
Немає даних
@@ -367,13 +368,13 @@
Жодного результату
Виберіть мережу
Оберіть гаманець
- 1 міс.
- 1 рік
- 24 год.
- 3 міс.
- 6 міс.
+ 1м
+ 1р
+ 24г
+ 3м
+ 6м
7д
- Увесь
+ Усе
Досвідчені покупці
За рейтингом
Сортувати за
@@ -394,7 +395,7 @@
Загальна кількість монет, які доступні для торгівлі та перебувають в обігу на ринку
Досвідчені покупці
Мережеві покупці з додатковою вимогою мати не менше 100 вихідних транзакцій
- Повністю розведена ринкова капіталізація
+ Повн. розведена кап.
Загальна теоретична вартість криптовалюти, якщо всі монети, які могли б існувати, перебувають в обігу, включаючи ті, що не перебувають в обігу в даний час
Дата створення
Високий
@@ -661,6 +662,7 @@
Це призведе до видалення гаманця з застосунку. Сам гаманець можна додати знову.
Ім\'я
Сума для стейкінгу має бути не менше %s
+ Сума стейкінгу буде округлена до %1$s TRX відповідно до правил мережі.
Зняти кошти
Процентна ставка
Річний відсоток, який ви можете отримати, беручи участь у стейкінгу.
@@ -733,6 +735,7 @@
Транзакція обробляється! Наразі триває перевірка в блокчейні. Це може зайняти кілька хвилин.
Розблокування
Розблокувати
+ Розблокування
Вивід зі стейкінгу
Зняти зі стейкінгу
Виведення зі стейкінгу %s
@@ -875,6 +878,8 @@
Помилка активації
За рішенням розробників мережі BNB стандарт BEP-2 перестане підтримуватись у червні 2024 року. Щоб не втратити свої активи, їх необхідно конвертувати у стандарт BEP-20. Використовуйте функцію обміну, щоб перевести їх у мережу BNB Smart Chain.
Відключення мережі BNB Beacon Chain
+ Будь ласка, поповніть рахунок на %1$s для покриття комісії мережі
+ Недостатньо коштів для покриття комісії мережі
Можна краще
Вподобати
Зрозуміло!
diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml
index 12c3f39762..e58d6eaa30 100644
--- a/core/res/src/main/res/values/strings.xml
+++ b/core/res/src/main/res/values/strings.xml
@@ -567,7 +567,7 @@
Scan the card to change its settings. The changes will impact only the card you\'ve scanned and will not affect other cards tied to your wallet.
Get your card ready!
Already included in the entered address
- The commission amount is %s times the recommended amount. Make sure that the custom settings are correct.
+ Your commission amount is %s times higher than the recommended amount. Please review and adjust your custom settings.
You specified a commission below the recommended amount, which could cause a delay in your transaction. Continue?
Reason: %1$s\nCode: %2$s
The transaction is not completed
@@ -602,7 +602,7 @@
Total exceeds balance
A balance of at least %s is required to keep your account on the blockchain to prevent security risks. This amount will remain in your balance and cannot be withdrawn.
Existential deposit
- The commission amount is %s times the recommended amount. Make sure that the custom settings are correct.
+ Your commission amount is %s times higher than the recommended amount. Please review and adjust your custom settings.
Custom fee is high
Due to the peculiarities of the %1$s network, the fee for transferring the entire balance is higher. To reduce the commission, you can leave %2$s.
The fee is higher
@@ -648,6 +648,8 @@
The amount to stake must be at least %s
Staking amount will be rounded to %1$s TRX due to network rules.
Claim unstaked
+ Stake account fee
+ A staking account is a special account where staked SOL tokens are stored. It is created when you delegate your tokens to a validator to participate in transaction validation and earn rewards. A small fee is charged for creating the staking account, which is returned after the staking is completed.
Annual percentage rate
The annual percentage return you can earn from participating in staking.
APR
@@ -703,6 +705,7 @@
Block
Day
Each day
+ Each ~%1$ssec
Epoch
Era
Hour
@@ -719,6 +722,7 @@
The transaction is being processed! Validation is currently underway in the blockchain. This may take a few minutes.
Unbonding
Unlock
+ Unlocking
Unstaked
Unstaking
Unstaking assets %s
diff --git a/core/ui/src/main/java/com/tangem/core/ui/utils/DecimalFormatterExt.kt b/core/ui/src/main/java/com/tangem/core/ui/utils/DecimalFormatterExt.kt
index 2d685763e3..a251b0c9ed 100644
--- a/core/ui/src/main/java/com/tangem/core/ui/utils/DecimalFormatterExt.kt
+++ b/core/ui/src/main/java/com/tangem/core/ui/utils/DecimalFormatterExt.kt
@@ -138,7 +138,7 @@ fun String.parseToBigDecimal(decimals: Int): BigDecimal {
}
}
-fun BigDecimal.parseBigDecimal(decimals: Int, roundingMode: RoundingMode = RoundingMode.DOWN): String {
+fun BigDecimal.parseBigDecimal(decimals: Int, roundingMode: RoundingMode = RoundingMode.HALF_UP): String {
val decimalFormat = DecimalFormat().apply {
decimalFormatSymbols = DecimalFormatSymbols(Locale.getDefault())
isParseBigDecimal = true
diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/TokenListSortingOperations.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/TokenListSortingOperations.kt
index 354252452c..7e4bc12ae2 100644
--- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/TokenListSortingOperations.kt
+++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/TokenListSortingOperations.kt
@@ -7,7 +7,9 @@ import arrow.core.raise.either
import arrow.core.raise.ensure
import arrow.core.raise.ensureNotNull
import arrow.core.toNonEmptyListOrNull
+import com.tangem.domain.staking.model.stakekit.YieldBalance
import com.tangem.domain.tokens.model.*
+import com.tangem.utils.extensions.orZero
import java.math.BigDecimal
internal class TokenListSortingOperations(
@@ -83,7 +85,7 @@ internal class TokenListSortingOperations(
return if (isAnyTokenLoading) {
tokens
} else {
- tokens.sortedByDescending { it.value.fiatAmount ?: BigDecimal.ZERO }
+ tokens.sortedByDescending { it.getTotalBalance() }
.toNonEmptyListOrNull()
?: error("Tokens can not be empty here")
}
@@ -92,12 +94,20 @@ internal class TokenListSortingOperations(
private fun sortGroupsByBalance(groupsWithSortedTokens: NonEmptyList): NonEmptyList {
return groupsWithSortedTokens
.sortedByDescending { group ->
- group.currencies.sumOf { it.value.fiatAmount ?: BigDecimal.ZERO }
+ group.currencies.sumOf { it.getTotalBalance() }
}
.toNonEmptyListOrNull()
?: error("Tokens can not be empty here")
}
+ private fun CryptoCurrencyStatus.getTotalBalance(): BigDecimal {
+ val yieldBalance = value.yieldBalance as? YieldBalance.Data
+ val totalYieldBalance = yieldBalance?.getTotalWithRewardsStakingBalance().orZero()
+ val totalFiatYieldBalance = totalYieldBalance.multiply(value.fiatRate.orZero())
+
+ return value.fiatAmount?.plus(totalFiatYieldBalance).orZero()
+ }
+
sealed class Error {
object EmptyTokens : Error()
diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetInitialDataStateTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetInitialDataStateTransformer.kt
index c2a2c681a5..9ed92bf14b 100644
--- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetInitialDataStateTransformer.kt
+++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetInitialDataStateTransformer.kt
@@ -19,6 +19,7 @@ import com.tangem.features.staking.impl.presentation.state.bottomsheet.InfoType
import com.tangem.features.staking.impl.presentation.state.converters.RewardsValidatorStateConverter
import com.tangem.features.staking.impl.presentation.state.converters.YieldBalancesConverter
import com.tangem.features.staking.impl.presentation.viewmodel.StakingClickIntents
+import com.tangem.lib.crypto.BlockchainUtils.isCosmos
import com.tangem.lib.crypto.BlockchainUtils.isPolkadot
import com.tangem.utils.Provider
import com.tangem.utils.isNullOrZero
@@ -201,12 +202,12 @@ internal class SetInitialDataStateTransformer(
private fun createRewardScheduleItem(
rewardSchedule: Yield.Metadata.RewardSchedule,
): RoundedListWithDividersItemData? {
- val endTextId = rewardScheduleResources[rewardSchedule] ?: return null
+ val endTextReference = getRewardScheduleText(rewardSchedule) ?: return null
return RoundedListWithDividersItemData(
id = R.string.staking_details_reward_schedule,
- startText = TextReference.Res(R.string.staking_details_reward_schedule),
- endText = TextReference.Res(endTextId),
+ startText = resourceReference(R.string.staking_details_reward_schedule),
+ endText = endTextReference,
iconClick = { clickIntents.onInfoClick(InfoType.REWARD_SCHEDULE) },
)
}
@@ -252,21 +253,34 @@ internal class SetInitialDataStateTransformer(
return resourceReference(R.string.common_range, wrappedList(formattedMinApr, formattedMaxApr))
}
- companion object {
- private val EQUALITY_THRESHOLD = BigDecimal(1E-10)
+ private fun getRewardScheduleText(rewardSchedule: Yield.Metadata.RewardSchedule): TextReference? {
+ return when (rewardSchedule) {
+ Yield.Metadata.RewardSchedule.BLOCK -> {
+ val networkId = cryptoCurrencyStatusProvider().currency.network.id.value
+ when {
+ isCosmos(networkId) -> resourceReference(
+ R.string.staking_reward_schedule_each_sec,
+ wrappedList(COSMOS_BLOCK_TIME),
+ )
+ else -> resourceReference(R.string.staking_reward_schedule_each_day)
+ }
+ }
+ Yield.Metadata.RewardSchedule.WEEK -> resourceReference(R.string.staking_reward_schedule_week)
+ Yield.Metadata.RewardSchedule.HOUR -> resourceReference(R.string.staking_reward_schedule_hour)
+ Yield.Metadata.RewardSchedule.DAY -> resourceReference(R.string.staking_reward_schedule_each_day)
+ Yield.Metadata.RewardSchedule.MONTH -> resourceReference(R.string.staking_reward_schedule_month)
+ Yield.Metadata.RewardSchedule.ERA -> resourceReference(R.string.staking_reward_schedule_era)
+ Yield.Metadata.RewardSchedule.EPOCH -> resourceReference(R.string.staking_reward_schedule_epoch)
+ Yield.Metadata.RewardSchedule.UNKNOWN -> null
+ }
+ }
- private val rewardScheduleResources = mapOf(
- Yield.Metadata.RewardSchedule.BLOCK to R.string.staking_reward_schedule_each_day,
- Yield.Metadata.RewardSchedule.WEEK to R.string.staking_reward_schedule_week,
- Yield.Metadata.RewardSchedule.HOUR to R.string.staking_reward_schedule_hour,
- Yield.Metadata.RewardSchedule.DAY to R.string.staking_reward_schedule_each_day,
- Yield.Metadata.RewardSchedule.MONTH to R.string.staking_reward_schedule_month,
- Yield.Metadata.RewardSchedule.ERA to R.string.staking_reward_schedule_era,
- Yield.Metadata.RewardSchedule.EPOCH to R.string.staking_reward_schedule_epoch,
- Yield.Metadata.RewardSchedule.UNKNOWN to null,
- )
+ private companion object {
+ val EQUALITY_THRESHOLD = BigDecimal(1E-10)
- private val rewardClaimingResources = mapOf(
+ const val COSMOS_BLOCK_TIME = "20" // 20 seconds
+
+ val rewardClaimingResources = mapOf(
Yield.Metadata.RewardClaiming.MANUAL to R.string.staking_reward_claiming_manual,
Yield.Metadata.RewardClaiming.AUTO to R.string.staking_reward_claiming_auto,
Yield.Metadata.RewardSchedule.UNKNOWN to null,
diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsBalanceSelectStateConverter.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsBalanceSelectStateConverter.kt
index 7695aa744c..0625d38565 100644
--- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsBalanceSelectStateConverter.kt
+++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsBalanceSelectStateConverter.kt
@@ -2,6 +2,7 @@ package com.tangem.feature.tokendetails.presentation.tokendetails.state.factory
import com.tangem.core.ui.utils.BigDecimalFormatter
import com.tangem.domain.appcurrency.model.AppCurrency
+import com.tangem.domain.staking.model.stakekit.YieldBalance
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.feature.tokendetails.presentation.tokendetails.state.*
import com.tangem.feature.tokendetails.presentation.tokendetails.state.utils.getBalance
@@ -20,8 +21,9 @@ internal class TokenDetailsBalanceSelectStateConverter(
if (stakingBlocksState !is StakingBlockUM.Staked) return this
val cryptoCurrencyStatus = cryptoCurrencyStatusProvider() ?: return this
- val stakingCryptoAmount = stakingBlocksState.cryptoAmount
- val stakingFiatAmount = stakingBlocksState.fiatAmount
+ val yieldBalance = cryptoCurrencyStatus.value.yieldBalance as? YieldBalance.Data
+ val stakingCryptoAmount = yieldBalance?.getTotalWithRewardsStakingBalance()
+ val stakingFiatAmount = stakingCryptoAmount?.let { cryptoCurrencyStatus.value.fiatRate?.multiply(it) }
copy(
tokenBalanceBlockState = if (tokenBalanceBlockState is TokenDetailsBalanceBlockState.Content) {
diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsLoadedBalanceConverter.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsLoadedBalanceConverter.kt
index 2419e894d1..190a186493 100644
--- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsLoadedBalanceConverter.kt
+++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsLoadedBalanceConverter.kt
@@ -153,8 +153,9 @@ internal class TokenDetailsLoadedBalanceConverter(
StakingBlockUM.Error(iconState = iconState)
}
else -> {
- val stakingRewardAmount = yieldBalance?.getRewardStakingBalance()
- val stakingFiatAmount = stakingCryptoAmount?.let { status.value.fiatRate?.multiply(it) }
+ val fiatRate = status.value.fiatRate
+ val stakingRewardAmount = yieldBalance?.getRewardStakingBalance()?.let { fiatRate?.multiply(it) }
+ val stakingFiatAmount = stakingCryptoAmount?.let { fiatRate?.multiply(it) }
getStakedState(
status = status,