Updated on 2026-08-14

This commit is contained in:
Tangem 2025-03-12 11:33:24 +03:00
commit 8148f32272
642 changed files with 10717 additions and 5789 deletions

View file

@ -40,6 +40,7 @@ sealed class AppRoute(val path: String) : Route {
val isTosAccepted: Boolean,
) : AppRoute(path = "/disclaimer${if (isTosAccepted) "/tos_accepted" else ""}")
@Deprecated("Do not use! Should be replaced by an implementation in onboarding component")
@Serializable
data object OnboardingNote : AppRoute(path = "/onboarding/note")
@ -68,15 +69,7 @@ sealed class AppRoute(val path: String) : Route {
data class CurrencyDetails(
val userWalletId: UserWalletId,
val currency: CryptoCurrency,
) : AppRoute(path = "/currency_details/${userWalletId.stringValue}/${currency.id.value}"), RouteBundleParams {
override fun getBundle(): Bundle = bundle(serializer())
companion object {
const val USER_WALLET_ID_KEY = "userWalletId"
const val CRYPTO_CURRENCY_KEY = "currency"
}
}
) : AppRoute(path = "/currency_details/${userWalletId.stringValue}/${currency.id.value}")
@Serializable
data class Send(
@ -92,20 +85,7 @@ sealed class AppRoute(val path: String) : Route {
"&$amount" +
"&$tag" +
"&$destinationAddress",
),
RouteBundleParams {
override fun getBundle(): Bundle = bundle(serializer())
companion object {
const val USER_WALLET_ID_KEY = "userWalletId"
const val CRYPTO_CURRENCY_KEY = "currency"
const val TRANSACTION_ID_KEY = "transactionId"
const val AMOUNT_KEY = "amount"
const val TAG_KEY = "tag"
const val DESTINATION_ADDRESS_KEY = "destinationAddress"
}
}
)
@Serializable
data class Details(
@ -115,22 +95,12 @@ sealed class AppRoute(val path: String) : Route {
@Serializable
data class DetailsSecurity(
val userWalletId: UserWalletId,
) : AppRoute(path = "/details/security"), RouteBundleParams {
override fun getBundle(): Bundle = bundle(serializer())
}
) : AppRoute(path = "/details/security")
@Serializable
data class CardSettings(
val userWalletId: UserWalletId,
) : AppRoute(path = "/card_settings/${userWalletId.stringValue}"), RouteBundleParams {
override fun getBundle(): Bundle = bundle(serializer())
companion object {
const val USER_WALLET_ID_KEY = "userWalletId"
}
}
) : AppRoute(path = "/card_settings/${userWalletId.stringValue}")
@Serializable
data object AppSettings : AppRoute(path = "/app_settings")
@ -155,31 +125,16 @@ sealed class AppRoute(val path: String) : Route {
"/$cardId" +
"/$isActiveBackupStatus" +
"/$backupCardsCount",
),
RouteBundleParams {
override fun getBundle(): Bundle = bundle(serializer())
companion object {
const val USER_WALLET_ID = "userWalletId"
const val CARD_ID = "cardId"
const val IS_ACTIVE_BACKUP_STATUS = "isActiveBackupStatus"
const val BACKUP_CARDS_COUNT = "backupCardsCount"
}
}
)
@Serializable
data object AccessCodeRecovery : AppRoute(path = "/access_code_recovery"), RouteBundleParams {
override fun getBundle(): Bundle = bundle(serializer())
}
data object AccessCodeRecovery : AppRoute(path = "/access_code_recovery")
@Serializable
data class ManageTokens(
val source: Source,
val userWalletId: UserWalletId? = null,
) : AppRoute(path = "${source.name.lowercase()}/manage_tokens/$userWalletId"), RouteBundleParams {
override fun getBundle(): Bundle = bundle(serializer())
) : AppRoute(path = "${source.name.lowercase()}/manage_tokens/$userWalletId") {
enum class Source {
STORIES,
@ -195,27 +150,12 @@ sealed class AppRoute(val path: String) : Route {
data class QrScanning(
val source: SourceType,
val networkName: String? = null,
) : AppRoute(path = "/$source/qr_scanning${if (networkName != null) "/$networkName" else ""}"), RouteBundleParams {
override fun getBundle(): Bundle = bundle(serializer())
companion object {
const val SOURCE_KEY = "source"
const val NETWORK_KEY = "networkName"
}
}
) : AppRoute(path = "/$source/qr_scanning${if (networkName != null) "/$networkName" else ""}")
@Serializable
data class ReferralProgram(
val userWalletId: UserWalletId,
) : AppRoute(path = "/referral_program"), RouteBundleParams {
override fun getBundle(): Bundle = bundle(serializer())
companion object {
const val USER_WALLET_ID_KEY = "userWalletId"
}
}
) : AppRoute(path = "/referral_program")
@Serializable
data class Swap(
@ -230,22 +170,12 @@ sealed class AppRoute(val path: String) : Route {
"/${currencyTo?.id?.value}" +
"/${userWalletId.stringValue}" +
"/$isInitialReverseOrder",
),
RouteBundleParams {
override fun getBundle(): Bundle = bundle(serializer())
companion object {
const val CURRENCY_FROM_KEY = "currencyFrom"
const val CURRENCY_TO_KEY = "currencyTo"
const val USER_WALLET_ID_KEY = "userWalletId"
const val IS_INITIAL_REVERSE_ORDER = "isInitialReverseOrder"
}
}
)
@Serializable
data object TesterMenu : AppRoute(path = "/tester_menu")
@Deprecated("Do not use! Should be replaced by an implementation in wallet route component")
@Serializable
data object SaveWallet : AppRoute(path = "/save_wallet")
@ -337,7 +267,5 @@ sealed class AppRoute(val path: String) : Route {
val storyId: String,
val nextScreen: AppRoute,
val screenSource: String,
) : AppRoute(path = "/stories$storyId"), RouteBundleParams {
override fun getBundle(): Bundle = bundle(serializer())
}
) : AppRoute(path = "/stories$storyId")
}

View file

@ -27,6 +27,7 @@ dependencies {
/** Project - Common */
implementation(projects.core.ui)
implementation(projects.core.utils)
implementation(projects.libs.crypto)
/** Project - Domain */
implementation(projects.domain.appCurrency.models)

View file

@ -8,7 +8,7 @@ sealed class NavigationButtonsState {
data object Empty : NavigationButtonsState()
data class Data(
val primaryButton: NavigationButton,
val primaryButton: NavigationButton?,
val prevButton: NavigationButton?,
val extraButtons: ImmutableList<NavigationButton>,
val txUrl: String? = null,

View file

@ -297,6 +297,21 @@ sealed class NotificationUM(val config: NotificationConfig) {
)
}
sealed interface Sui {
data object NotEnoughCoinForTokenTransaction : Error(
title = resourceReference(id = R.string.sui_not_enough_coin_for_fee_title),
subtitle = resourceReference(
id = R.string.sui_not_enough_coin_for_fee_description,
formatArgs = wrappedList(
BigDecimal.ONE.format {
crypto(Blockchain.Sui.currency, Blockchain.Sui.decimals())
},
),
),
)
}
sealed interface Koinos {
data class InsufficientRecoverableMana(
val mana: BigDecimal,

View file

@ -66,6 +66,8 @@ object NotificationsFactory {
},
),
)
is GetFeeError.BlockchainErrors.SuiOneCoinRequired ->
add(NotificationUM.Sui.NotEnoughCoinForTokenTransaction)
is GetFeeError.DataError,
is GetFeeError.UnknownError,
-> add(
@ -364,6 +366,7 @@ object NotificationsFactory {
)
}
}
else -> return
}
}

View file

@ -15,6 +15,7 @@ import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.models.StatusSource
import com.tangem.domain.staking.model.stakekit.YieldBalance
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.lib.crypto.BlockchainUtils
import com.tangem.utils.StringsSigns.DASH_SIGN
import com.tangem.utils.converter.Converter
import com.tangem.utils.extensions.isZero
@ -199,7 +200,11 @@ class TokenItemStateConverter(
is CryptoCurrencyStatus.NoAccount,
-> {
TokenItemState.Subtitle2State.TextContent(
text = status.getFormattedCryptoAmount(includeStaking = true),
text = status.getFormattedCryptoAmount(
includeStaking = BlockchainUtils.isIncludeStakingTotalBalance(
status.currency.network.id.value,
),
),
isFlickering = status.value.isFlickering(),
)
}
@ -222,7 +227,12 @@ class TokenItemStateConverter(
is CryptoCurrencyStatus.NoAccount,
-> {
TokenItemState.FiatAmountState.Content(
text = status.getFormattedFiatAmount(appCurrency = appCurrency, includeStaking = true),
text = status.getFormattedFiatAmount(
appCurrency = appCurrency,
includeStaking = BlockchainUtils.isIncludeStakingTotalBalance(
status.currency.network.id.value,
),
),
isFlickering = status.value.isFlickering(),
icons = buildList {
if (!status.getStakedBalance().isZero()) {