Updated on 2026-08-14

This commit is contained in:
Tangem 2024-01-30 12:49:58 +03:00
parent 222bfd9a3a
commit 885db20951
19 changed files with 81 additions and 20 deletions

View file

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<string name="common_fee_error">Erhalt der Gebühr fehlgeschlagen</string>
<string name="no_account_bnb">Senden Sie Geld an diese Andresse um ein Konto zu erstellen</string>
<string name="send_error_dust_amount_format">Minimaler Betrag ist %s</string>
<string name="send_error_dust_change">Restbestand zu klein</string>
<string name="send_error_invalid_fee_value">Falsche Gebühr</string>

View file

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<string name="common_fee_error">Échec de réception des commissions</string>
<string name="no_account_bnb">Pour créer un compte, envoyez des fonds monétaires à cette adresse</string>
<string name="send_error_dust_amount_format">Le montant minimal est de %s</string>
<string name="send_error_dust_change">Le reste est trop petit</string>
<string name="send_error_invalid_fee_value">Commission non valide</string>

View file

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<string name="common_fee_error">Impossibile ottenere la commissione</string>
<string name="no_account_bnb">Per creare un account, invia fondi a questo indirizzo</string>
<string name="send_error_dust_amount_format">L\'importo minimo è di %s</string>
<string name="send_error_dust_change">L\'importo residuo è molto basso</string>
<string name="send_error_invalid_fee_value">Commissione non valida</string>

View file

@ -6,8 +6,8 @@
<string name="common_utxo_validate_withdrawal_message_warning">Из-за ограничений %1$s в одну транзакцию может поместиться только %2$d UTXO. Это означает, что вы можете отправить только %3$s или меньше. Вам нужно уменьшить сумму.</string>
<string name="eth_gas_required_exceeds_allowance">Недостаточно средств для совершения транзакции. Пожалуйста, пополните свой аккаунт.</string>
<string name="generic_error_code">Произошла ошибка. Код: %s.</string>
<string name="kaspa_withdrawal_message_warning">Из-за ограничений Kaspa в одну транзакцию может поместиться только %1$d UTXO. Это означает, что вы можете отправить только %2$s или меньше. Вам нужно уменьшить сумму.</string>
<string name="no_account_generic">Чтобы использовать сеть %1$s, вы должны оплатить резерв аккаунта (%2$s %3$s), который блокируется и не используется в вашем балансе.</string>
<string name="no_account_bnb">Для создания аккаунта отправьте средства на этот адрес</string>
<string name="no_account_generic">Чтобы использовать сеть %1$s, вы должны оплатить резерв аккаунта (%2$s %3$s), который блокируется и не используется в вашем балансе</string>
<string name="no_account_polkadot">Аккаунт получателя не активирован. Отправьте %s или более для активации аккаунта.</string>
<string name="send_error_dust_amount_format">Минимальная сумма: %s</string>
<string name="send_error_dust_change">Сдача слишком мала</string>

View file

@ -4,6 +4,7 @@
<string name="address_type_legacy">遺留資產</string>
<string name="common_fee_error">獲取費用失敗</string>
<string name="kaspa_withdrawal_message_warning">由於 Kaspa 的限制,只有%1$d UTXO 可以放入單次交易中。這意味著您只能發送%2$s或更少數量。您需要減少數量。</string>
<string name="no_account_bnb">要創建帳戶,請將資金發送到此地址</string>
<string name="no_account_polkadot">目標帳戶未激活。發送 %s 或更多以激活帳戶</string>
<string name="send_error_dust_amount_format">最小數量是 %s</string>
<string name="send_error_dust_change">更動太小</string>

View file

@ -7,7 +7,8 @@
<string name="eth_gas_required_exceeds_allowance">Not enough funds for the transaction. Please top up your account.</string>
<string name="generic_error_code">An error occurred. Code: %s.</string>
<string name="kaspa_withdrawal_message_warning">Due to Kaspa limitations only %1$d UTXOs can fit in a single transaction. This means you can only send %2$s or less. You need to reduce the amount.</string>
<string name="no_account_generic">To use the %1$s network, you must pay the account reserve (%2$s %3$s), which locks up and hides that amount indefinitely.</string>
<string name="no_account_bnb">To create account send funds to this address</string>
<string name="no_account_generic">To use the %1$s network, you must pay the account reserve (%2$s %3$s), which locks up and hides that amount indefinitely</string>
<string name="no_account_polkadot">Destination account is not active. Send %s or more to activate the account.</string>
<string name="send_error_dust_amount_format">Minimum amount is %s</string>
<string name="send_error_dust_change">Change is too small</string>

View file

@ -48,6 +48,7 @@ fun getActiveIconRes(blockchainId: String): Int {
"decimal", "decimal/test" -> R.drawable.img_decimal_22
"xdc", "xdc/test" -> R.drawable.img_xdc_22
"vechain", "vechain/test" -> R.drawable.img_vechain_22
"aptos", "aptos/test" -> R.drawable.img_aptos_22
else -> R.drawable.ic_alert_24
}
}
@ -97,6 +98,7 @@ fun getActiveIconResByNetworkId(networkId: String): Int {
"decimal", "decimal/test" -> R.drawable.img_decimal_22
"xdc-network", "xdc-network/test" -> R.drawable.img_xdc_22
"vechain", "vechain/test" -> R.drawable.img_vechain_22
"aptos", "aptos/test" -> R.drawable.img_aptos_22
else -> R.drawable.ic_alert_24
}
}
@ -143,6 +145,7 @@ fun getActiveIconResByCoinId(coinId: String): Int {
"decimal" -> R.drawable.img_decimal_22
"xdce-crowd-sale" -> R.drawable.img_xdc_22
"vechain" -> R.drawable.img_vechain_22
"aptos" -> R.drawable.img_aptos_22
else -> R.drawable.ic_alert_24
}
}
@ -192,6 +195,7 @@ fun getGreyedOutIconRes(blockchainId: String): Int {
"decimal", "decimal/test" -> R.drawable.ic_decimal_22
"xdc", "xdc/test" -> R.drawable.ic_xdc_22
"vechain", "vechain/test" -> R.drawable.ic_vechain_22
"aptos", "aptos/test" -> R.drawable.ic_aptos_22
else -> R.drawable.ic_alert_24
}
}
@ -241,6 +245,7 @@ fun getGreyedOutIconResByNetworkId(networkId: String): Int {
"decimal", "decimal/test" -> R.drawable.ic_decimal_22
"xdc-network", "xdc-network/test" -> R.drawable.ic_xdc_22
"vechain", "vechain/test" -> R.drawable.ic_vechain_22
"aptos", "aptos/test" -> R.drawable.ic_aptos_22
else -> R.drawable.ic_alert_24
}
}

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="22dp"
android:height="22dp"
android:viewportWidth="22"
android:viewportHeight="22">
<path
android:pathData="M12.624,7.396C12.72,7.396 12.812,7.357 12.879,7.288L13.39,6.757C13.453,6.691 13.542,6.653 13.634,6.653H13.655C13.752,6.653 13.844,6.694 13.908,6.767L14.338,7.251C14.42,7.343 14.538,7.396 14.662,7.396H15.815C14.717,5.941 12.969,5 11,5C9.032,5 7.285,5.941 6.186,7.396H12.624ZM13.232,9.014H14.294V9.015H16.684C16.849,9.485 16.957,9.981 17,10.496H12.523C12.399,10.496 12.282,10.443 12.2,10.351L11.769,9.866C11.705,9.794 11.613,9.753 11.516,9.753H11.495C11.403,9.753 11.315,9.79 11.251,9.857L10.74,10.387C10.674,10.457 10.582,10.496 10.485,10.496H5C5.043,9.981 5.151,9.485 5.316,9.015H11.126C11.308,9.015 11.482,8.937 11.603,8.801L11.972,8.385C12.036,8.312 12.129,8.271 12.225,8.271C12.322,8.271 12.415,8.313 12.479,8.385L12.909,8.869C12.991,8.961 13.109,9.014 13.232,9.014ZM8.575,13.5C8.508,13.57 8.416,13.609 8.32,13.609V13.609H5.576C5.349,13.142 5.182,12.64 5.083,12.114H8.988C9.171,12.114 9.344,12.036 9.465,11.9L9.835,11.484C9.899,11.411 9.991,11.37 10.088,11.37C10.184,11.37 10.277,11.412 10.341,11.484L10.771,11.968C10.853,12.06 10.971,12.113 11.094,12.113H16.918C16.819,12.639 16.652,13.141 16.425,13.609H10.358C10.234,13.609 10.117,13.556 10.034,13.464L9.604,12.98C9.54,12.907 9.448,12.866 9.351,12.866H9.33C9.238,12.866 9.149,12.903 9.086,12.97L8.575,13.5ZM8.728,15.092H10.306V15.092H15.403C14.303,16.266 12.738,17 11,17C9.262,17 7.697,16.266 6.597,15.092H6.622C6.805,15.092 6.978,15.014 7.099,14.878L7.468,14.462C7.532,14.39 7.625,14.349 7.722,14.349C7.818,14.349 7.911,14.39 7.975,14.462L8.405,14.947C8.487,15.039 8.605,15.092 8.728,15.092Z"
android:fillColor="#000000"
android:fillType="evenOdd" />
</vector>

View file

@ -0,0 +1,16 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="22dp"
android:height="22dp"
android:viewportWidth="22"
android:viewportHeight="22">
<group>
<clip-path android:pathData="M11,0L11,0A11,11 0,0 1,22 11L22,11A11,11 0,0 1,11 22L11,22A11,11 0,0 1,0 11L0,11A11,11 0,0 1,11 0z" />
<path
android:pathData="M11,0L11,0A11,11 0,0 1,22 11L22,11A11,11 0,0 1,11 22L11,22A11,11 0,0 1,0 11L0,11A11,11 0,0 1,11 0z"
android:fillColor="#000000" />
<path
android:pathData="M12.624,7.396C12.72,7.396 12.812,7.357 12.879,7.288L13.39,6.757C13.453,6.691 13.542,6.653 13.634,6.653H13.655C13.752,6.653 13.844,6.694 13.908,6.767L14.338,7.251C14.42,7.343 14.538,7.396 14.662,7.396H15.815C14.717,5.941 12.969,5 11,5C9.032,5 7.285,5.941 6.186,7.396H12.624ZM13.232,9.014H14.294V9.015H16.684C16.849,9.485 16.957,9.981 17,10.496H12.523C12.399,10.496 12.282,10.443 12.2,10.351L11.769,9.866C11.705,9.794 11.613,9.753 11.516,9.753H11.495C11.403,9.753 11.315,9.79 11.251,9.857L10.74,10.387C10.674,10.457 10.582,10.496 10.485,10.496H5C5.043,9.981 5.151,9.485 5.316,9.015H11.126C11.308,9.015 11.482,8.937 11.603,8.801L11.972,8.385C12.036,8.312 12.129,8.271 12.225,8.271C12.322,8.271 12.415,8.313 12.479,8.385L12.909,8.869C12.991,8.961 13.109,9.014 13.232,9.014ZM8.575,13.5C8.508,13.57 8.416,13.609 8.32,13.609V13.609H5.576C5.349,13.142 5.182,12.64 5.083,12.114H8.988C9.171,12.114 9.344,12.036 9.465,11.9L9.835,11.484C9.899,11.411 9.991,11.37 10.088,11.37C10.184,11.37 10.277,11.412 10.341,11.484L10.771,11.968C10.853,12.06 10.971,12.113 11.094,12.113H16.918C16.819,12.639 16.652,13.141 16.425,13.609H10.358C10.234,13.609 10.117,13.556 10.034,13.464L9.604,12.98C9.54,12.907 9.448,12.866 9.351,12.866H9.33C9.238,12.866 9.149,12.903 9.086,12.97L8.575,13.5ZM8.728,15.092H10.306V15.092H15.403C14.303,16.266 12.738,17 11,17C9.262,17 7.697,16.266 6.597,15.092H6.622C6.805,15.092 6.978,15.014 7.099,14.878L7.468,14.462C7.532,14.39 7.625,14.349 7.722,14.349C7.818,14.349 7.911,14.39 7.975,14.462L8.405,14.947C8.487,15.039 8.605,15.092 8.728,15.092Z"
android:fillColor="#ffffff"
android:fillType="evenOdd" />
</group>
</vector>

View file

@ -1,5 +1,6 @@
package com.tangem.data.tokens.repository
import com.tangem.blockchain.common.Blockchain
import com.tangem.data.common.cache.CacheRegistry
import com.tangem.data.tokens.utils.CardCryptoCurrenciesFactory
import com.tangem.data.tokens.utils.NetworkStatusFactory
@ -7,6 +8,7 @@ import com.tangem.data.tokens.utils.ResponseCryptoCurrenciesFactory
import com.tangem.datasource.local.network.NetworksStatusesStore
import com.tangem.datasource.local.token.UserTokensStore
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.domain.common.extensions.fromNetworkId
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.domain.demo.DemoConfig
import com.tangem.domain.tokens.model.CryptoCurrency
@ -68,6 +70,11 @@ internal class DefaultNetworksRepository(
networksStatusesStore.getSyncOrNull(userWalletId).orEmpty()
}
override fun isNeedToCreateAccountWithoutReserve(network: Network): Boolean {
val blockchain = Blockchain.fromNetworkId(network.id.value)
return blockchain == Blockchain.Aptos
}
private suspend fun fetchNetworksStatusesIfCacheExpired(
userWalletId: UserWalletId,
networks: Set<Network>,

View file

@ -225,6 +225,7 @@ fun Blockchain.amountToCreateAccount(token: Token? = null): BigDecimal? {
Blockchain.Stellar -> if (token?.symbol == NODL) BigDecimal(NODL_AMOUNT_TO_CREATE_ACCOUNT) else BigDecimal.ONE
Blockchain.XRP -> BigDecimal.TEN
Blockchain.Near, Blockchain.NearTestnet -> 0.00182.toBigDecimal()
Blockchain.Aptos, Blockchain.AptosTestnet -> BigDecimal.ZERO
else -> null
}
}
@ -239,4 +240,5 @@ private const val NODL_AMOUNT_TO_CREATE_ACCOUNT = 1.5
private val excludedBlockchains = listOf(
Blockchain.Unknown,
Blockchain.Ducatus,
Blockchain.Aptos,
)

View file

@ -30,6 +30,8 @@ sealed class CryptoCurrencyWarning {
val amountCurrency: CryptoCurrency,
) : CryptoCurrencyWarning()
object TopUpWithoutReserve : CryptoCurrencyWarning()
/**
* Represents wallet blockchain rent
* @param rent Amount that will be charged in overtime if the blockchain does not have an amount greater than

View file

@ -251,10 +251,14 @@ class GetCurrencyWarningsUseCase(
private fun getNetworkNoAccountWarning(currencyStatus: CryptoCurrencyStatus): CryptoCurrencyWarning? {
return (currencyStatus.value as? CryptoCurrencyStatus.NoAccount)?.let {
CryptoCurrencyWarning.SomeNetworksNoAccount(
amountToCreateAccount = it.amountToCreateAccount,
amountCurrency = currencyStatus.currency,
)
if (networksRepository.isNeedToCreateAccountWithoutReserve(network = currencyStatus.currency.network)) {
CryptoCurrencyWarning.TopUpWithoutReserve
} else {
CryptoCurrencyWarning.SomeNetworksNoAccount(
amountToCreateAccount = it.amountToCreateAccount,
amountCurrency = currencyStatus.currency,
)
}
}
}

View file

@ -43,4 +43,6 @@ interface NetworksRepository {
networks: Set<Network>,
refresh: Boolean,
): Set<NetworkStatus>
fun isNeedToCreateAccountWithoutReserve(network: Network): Boolean
}

View file

@ -32,4 +32,6 @@ internal class MockNetworksRepository(
): Set<NetworkStatus> {
return getNetworkStatusesUpdates(userWalletId, networks).first()
}
override fun isNeedToCreateAccountWithoutReserve(network: Network) = false
}

View file

@ -39,6 +39,7 @@ internal class TokenDetailsNotificationsAnalyticsSender(
is TokenDetailsNotification.ExistentialDeposit,
is TokenDetailsNotification.HasPendingTransactions,
is TokenDetailsNotification.NetworksNoAccount,
is TokenDetailsNotification.TopUpWithoutReserve,
is TokenDetailsNotification.RentInfo,
is TokenDetailsNotification.SwapPromo,
-> null

View file

@ -147,6 +147,11 @@ internal sealed class TokenDetailsNotification(val config: NotificationConfig) {
),
)
object TopUpWithoutReserve : Informational(
title = resourceReference(id = R.string.warning_no_account_title),
subtitle = resourceReference(id = R.string.no_account_bnb),
)
class HasPendingTransactions(val coinSymbol: String) : Informational(
title = resourceReference(R.string.warning_send_blocked_pending_transactions_title),
subtitle = resourceReference(

View file

@ -3,6 +3,7 @@ package com.tangem.feature.tokendetails.presentation.tokendetails.state.factory
import com.tangem.domain.tokens.model.warnings.CryptoCurrencyWarning
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsState
import com.tangem.feature.tokendetails.presentation.tokendetails.state.components.TokenDetailsNotification
import com.tangem.feature.tokendetails.presentation.tokendetails.state.components.TokenDetailsNotification.*
import com.tangem.feature.tokendetails.presentation.tokendetails.viewmodels.TokenDetailsClickIntents
import com.tangem.utils.converter.Converter
import com.tangem.utils.extensions.removeBy
@ -19,13 +20,13 @@ internal class TokenDetailsNotificationConverter(
fun removeRentInfo(currentState: TokenDetailsState): ImmutableList<TokenDetailsNotification> {
val newNotifications = currentState.notifications.toMutableList()
newNotifications.removeBy { it is TokenDetailsNotification.RentInfo }
newNotifications.removeBy { it is RentInfo }
return newNotifications.toImmutableList()
}
private fun mapToNotification(warning: CryptoCurrencyWarning): TokenDetailsNotification {
return when (warning) {
is CryptoCurrencyWarning.BalanceNotEnoughForFee -> TokenDetailsNotification.NetworkFeeWithBuyButton(
is CryptoCurrencyWarning.BalanceNotEnoughForFee -> NetworkFeeWithBuyButton(
currency = warning.tokenCurrency,
networkName = warning.coinCurrency.name,
feeCurrencyName = warning.coinCurrency.name,
@ -35,7 +36,7 @@ internal class TokenDetailsNotificationConverter(
is CryptoCurrencyWarning.CustomTokenNotEnoughForFee -> {
val feeCurrency = warning.feeCurrency
if (feeCurrency != null) {
TokenDetailsNotification.NetworkFeeWithBuyButton(
NetworkFeeWithBuyButton(
currency = warning.currency,
networkName = feeCurrency.network.name,
feeCurrencyName = warning.feeCurrencyName,
@ -43,7 +44,7 @@ internal class TokenDetailsNotificationConverter(
onBuyClick = { clickIntents.onBuyCoinClick(feeCurrency) },
)
} else {
TokenDetailsNotification.NetworkFee(
NetworkFee(
currency = warning.currency,
networkName = warning.networkName,
feeCurrencyName = warning.feeCurrencyName,
@ -51,23 +52,22 @@ internal class TokenDetailsNotificationConverter(
)
}
}
is CryptoCurrencyWarning.ExistentialDeposit -> TokenDetailsNotification.ExistentialDeposit(
existentialInfo = warning,
)
is CryptoCurrencyWarning.Rent -> TokenDetailsNotification.RentInfo(
is CryptoCurrencyWarning.ExistentialDeposit -> ExistentialDeposit(existentialInfo = warning)
is CryptoCurrencyWarning.Rent -> RentInfo(
rentInfo = warning,
onCloseClick = clickIntents::onCloseRentInfoNotification,
)
CryptoCurrencyWarning.SomeNetworksUnreachable -> TokenDetailsNotification.NetworksUnreachable
is CryptoCurrencyWarning.SomeNetworksNoAccount -> TokenDetailsNotification.NetworksNoAccount(
CryptoCurrencyWarning.SomeNetworksUnreachable -> NetworksUnreachable
is CryptoCurrencyWarning.SomeNetworksNoAccount -> NetworksNoAccount(
network = warning.amountCurrency.name,
amount = warning.amountToCreateAccount.toString(),
symbol = warning.amountCurrency.symbol,
)
is CryptoCurrencyWarning.HasPendingTransactions -> TokenDetailsNotification.HasPendingTransactions(
is CryptoCurrencyWarning.TopUpWithoutReserve -> TopUpWithoutReserve
is CryptoCurrencyWarning.HasPendingTransactions -> HasPendingTransactions(
coinSymbol = warning.blockchainSymbol,
)
is CryptoCurrencyWarning.SwapPromo -> TokenDetailsNotification.SwapPromo(
is CryptoCurrencyWarning.SwapPromo -> SwapPromo(
onSwapClick = clickIntents::onSwapPromoClick,
onCloseClick = clickIntents::onSwapPromoDismiss,
)

View file

@ -85,7 +85,7 @@ spr-client = "3.6.2"
# endregion Other libraries
# region Tangem
tangemBlockchainSdk = "develop-463"
tangemBlockchainSdk = "develop-467"
#tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds
tangemCardSdk = "develop-319"
#tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^