Updated on 2026-08-14
This commit is contained in:
commit
b0ac045d0d
119 changed files with 2794 additions and 607 deletions
40
LICENSE
40
LICENSE
|
|
@ -2,17 +2,37 @@ Tangem Proprietary and Confidential
|
|||
Copyright (c) 2025 Tangem AG. All rights reserved.
|
||||
================================================================================
|
||||
NOTICE: THIS IS NOT AN OPEN SOURCE LICENSE.
|
||||
This software, including all source code, documentation, and accompanying files (the "Software") stored in this repository, is the proprietary and confidential information of Tangem AG ("Tangem"). The publication of this Software on a public platform does not grant any license, express or implied.
|
||||
|
||||
This software, including all source code, documentation, and accompanying files (the "Software") stored in this repository, is the proprietary and confidential information of Tangem AG ("Tangem").
|
||||
The publication of this Software on a public platform does not grant any license, express or implied, except as explicitly stated in Section 2 below.
|
||||
|
||||
1. Definitions.
|
||||
"Software" refers to all contents of this repository.
|
||||
"Protocol" refers to the proprietary communication protocol, including the sequence of, data structures, and cryptographic methods used to interact with Tangem hardware.
|
||||
"SDKs" refer to the official Software Development Kits (e.g., for Android, iOS, React Native) provided by Tangem in separate repositories and under their own distinct licenses.
|
||||
2. Strict Prohibition of Use. Any use of the Software, in whole or in part, is strictly prohibited without the express prior written consent of Tangem. This prohibition includes, but is not limited to, the following actions for any purpose, whether commercial or non-commercial:
|
||||
- Copying, modifying, or merging the Software.
|
||||
- Publishing, distributing, or sublicensing the Software.
|
||||
|
||||
2. Limited License for Personal Use and Contributions.
|
||||
Notwithstanding the proprietary nature of the Software, Tangem grants you a personal, non-exclusive, non-transferable, revocable license to:
|
||||
- Clone, fork, and modify the Software solely for personal, non-commercial purposes (e.g., for security auditing, verification, or building the application for installation on your personal device).
|
||||
- Use the Software to interact with Tangem hardware for personal needs.
|
||||
- Submit proposals for changes (Pull Requests) to improve the Software.
|
||||
|
||||
3. Strict Prohibition of Commercial Use and Distribution.
|
||||
Except for the rights expressly granted in Section 2, any use of the Software, in whole or in part, remains strictly prohibited without the express prior written consent of Tangem.
|
||||
This prohibition applies to any commercial purpose and includes, but is not limited to:
|
||||
- Publishing, distributing, or sublicensing the Software or its derivatives.
|
||||
- Selling copies of the Software.
|
||||
- Creating derivative works based on the Software.
|
||||
3. Protocol Usage. Reverse-engineering, analyzing, decompiling, or attempting to recreate the Protocol is strictly prohibited. The only authorized method for third-party applications to interact with Tangem hardware is by using the official Tangem SDKs. The SDKs are governed by their own license terms (e.g., MIT License), which permit their use in third-party applications. This Software is provided for transparency and reference purposes only.
|
||||
4. No Implied Rights. The act of Tangem publishing the Software to a public repository does not grant users any implied rights or licenses to use, modify, or distribute the Software. All rights not expressly granted by Tangem in a separate written agreement are reserved.
|
||||
5. Legal Action. Unauthorized use, reproduction, or distribution of the Software or the Protocol may result in severe civil and criminal penalties, and will be prosecuted to the maximum extent possible under applicable law.
|
||||
For inquiries about licensing or permissions to use the Software or the Protocol, please contact Tangem AG at: legal@tangem.com.
|
||||
- Creating a competing product or service based on the Software.
|
||||
- Integrating the Software or the Protocol into third-party commercial applications or services.
|
||||
|
||||
4. Protocol Usage.
|
||||
Reverse-engineering, decompiling, or attempting to recreate the Protocol for use in unauthorized applications is strictly prohibited.
|
||||
Any interaction with Tangem hardware in commercial or distributed applications requires a separate commercial agreement with Tangem.
|
||||
This Software is provided for transparency and reference purposes.
|
||||
|
||||
5. No Implied Rights.
|
||||
The act of Tangem publishing the Software to a public repository does not grant users any implied rights or licenses to use, modify, or distribute the Software beyond the limited permissions described in Section 2.
|
||||
All rights not expressly granted by Tangem in a separate written agreement are reserved.
|
||||
|
||||
6. Legal Action.
|
||||
Unauthorized use, reproduction, or distribution of the Software or the Protocol may result in severe civil and criminal penalties, and will be prosecuted to the maximum extent possible under applicable law.
|
||||
For inquiries about licensing or permissions to use the Software or the Protocol, please contact Tangem AG at: legal@tangem.com.
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit 76978242504ab90803b99e2b0575f7ebe8e69335
|
||||
Subproject commit 5fc86d29bc2c0dc7c057ab0242b2cfa3e9f48daf
|
||||
|
|
@ -35,7 +35,7 @@ internal class CustomTabsUrlOpener : UrlOpener {
|
|||
|
||||
private fun openUrl(url: String, context: Context) {
|
||||
if (url.isEmpty()) return
|
||||
val browserIntent = Intent(Intent.ACTION_VIEW, url.toUri())
|
||||
val browserIntent = Intent(Intent.ACTION_VIEW, url.trim().toUri())
|
||||
runCatching {
|
||||
if (checkCustomTabsAvailability(context, browserIntent)) {
|
||||
context.startActivity(browserIntent)
|
||||
|
|
|
|||
|
|
@ -18,8 +18,7 @@ import kotlinx.coroutines.withContext
|
|||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
private const val DEFAULT_KEY = "tangem_pay_default_key"
|
||||
private const val ORDER_ID_KEY = "tangem_pay_order_id_key"
|
||||
private const val AUTH_TOKENS_DEFAULT_KEY = "tangem_pay_default_key"
|
||||
private const val WITHDRAW_ORDER_ID_KEY = "tangem_pay_withdraw_order_id_key"
|
||||
|
||||
@Singleton
|
||||
|
|
@ -42,13 +41,15 @@ internal class DefaultTangemPayStorage @Inject constructor(
|
|||
|
||||
override suspend fun storeCustomerWalletAddress(userWalletId: UserWalletId, customerWalletAddress: String) {
|
||||
withContext(dispatcherProvider.io) {
|
||||
secureStorage.store(key = createCustomerAddressKey(userWalletId), value = customerWalletAddress)
|
||||
appPreferencesStore
|
||||
.store(PreferencesKeys.getTangemPayCustomerWalletAddressKey(userWalletId), customerWalletAddress)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getCustomerWalletAddress(userWalletId: UserWalletId): String? {
|
||||
return withContext(dispatcherProvider.io) {
|
||||
secureStorage.getAsString(createCustomerAddressKey(userWalletId))
|
||||
appPreferencesStore.getSyncOrNull(key = PreferencesKeys.getTangemPayCustomerWalletAddressKey(userWalletId))
|
||||
.takeIf { !it.isNullOrEmpty() }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -58,28 +59,28 @@ internal class DefaultTangemPayStorage @Inject constructor(
|
|||
|
||||
secureStorage.store(
|
||||
json.encodeToByteArray(throwOnInvalidSequence = true),
|
||||
createKey(customerWalletAddress),
|
||||
createAuthTokensKey(customerWalletAddress),
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun getAuthTokens(customerWalletAddress: String): TangemPayAuthTokens? =
|
||||
withContext(dispatcherProvider.io) {
|
||||
secureStorage.get(createKey(customerWalletAddress))
|
||||
secureStorage.get(createAuthTokensKey(customerWalletAddress))
|
||||
?.decodeToString(throwOnInvalidSequence = true)
|
||||
?.let(tokensAdapter::fromJson)
|
||||
}
|
||||
|
||||
override suspend fun storeOrderId(customerWalletAddress: String, orderId: String) {
|
||||
withContext(dispatcherProvider.io) {
|
||||
secureStorage.store(
|
||||
orderId.encodeToByteArray(throwOnInvalidSequence = true),
|
||||
createOrderIdKey(customerWalletAddress),
|
||||
)
|
||||
appPreferencesStore.store(PreferencesKeys.getTangemPayOrderIdKey(customerWalletAddress), orderId)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getOrderId(customerWalletAddress: String): String? = withContext(dispatcherProvider.io) {
|
||||
secureStorage.get(createOrderIdKey(customerWalletAddress))?.decodeToString(throwOnInvalidSequence = true)
|
||||
override suspend fun getOrderId(customerWalletAddress: String): String? {
|
||||
return withContext(dispatcherProvider.io) {
|
||||
appPreferencesStore.getSyncOrNull(key = PreferencesKeys.getTangemPayOrderIdKey(customerWalletAddress))
|
||||
.takeIf { !it.isNullOrEmpty() }
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getAddToWalletDone(customerWalletAddress: String): Boolean {
|
||||
|
|
@ -97,7 +98,7 @@ internal class DefaultTangemPayStorage @Inject constructor(
|
|||
}
|
||||
|
||||
override suspend fun clearOrderId(customerWalletAddress: String) = withContext(dispatcherProvider.io) {
|
||||
secureStorage.delete(createOrderIdKey(customerWalletAddress))
|
||||
appPreferencesStore.store(PreferencesKeys.getTangemPayOrderIdKey(customerWalletAddress), "")
|
||||
}
|
||||
|
||||
override suspend fun storeCheckCustomerWalletResult(userWalletId: UserWalletId, isPaeraCustomer: Boolean) {
|
||||
|
|
@ -110,9 +111,9 @@ internal class DefaultTangemPayStorage @Inject constructor(
|
|||
|
||||
override suspend fun clearAll(userWalletId: UserWalletId, customerWalletAddress: String) =
|
||||
withContext(dispatcherProvider.io) {
|
||||
secureStorage.delete(createCustomerAddressKey(userWalletId))
|
||||
secureStorage.delete(createKey(customerWalletAddress))
|
||||
secureStorage.delete(createOrderIdKey(customerWalletAddress))
|
||||
secureStorage.delete(createAuthTokensKey(customerWalletAddress))
|
||||
appPreferencesStore.store(PreferencesKeys.getTangemPayCustomerWalletAddressKey(userWalletId), "")
|
||||
appPreferencesStore.store(PreferencesKeys.getTangemPayOrderIdKey(customerWalletAddress), "")
|
||||
appPreferencesStore.store(PreferencesKeys.getTangemPayAddToWalletKey(customerWalletAddress), false)
|
||||
}
|
||||
|
||||
|
|
@ -143,11 +144,7 @@ internal class DefaultTangemPayStorage @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun createCustomerAddressKey(userWalletId: UserWalletId): String = userWalletId.stringValue
|
||||
|
||||
private fun createKey(address: String): String = "${DEFAULT_KEY}_$address"
|
||||
|
||||
private fun createOrderIdKey(address: String): String = "${ORDER_ID_KEY}_$address"
|
||||
private fun createAuthTokensKey(address: String): String = "${AUTH_TOKENS_DEFAULT_KEY}_$address"
|
||||
|
||||
private fun createWithdrawOrderIdKey(userWalletId: UserWalletId): String = "${WITHDRAW_ORDER_ID_KEY}_$userWalletId"
|
||||
}
|
||||
|
|
@ -199,4 +199,30 @@ internal object YieldSupplyDomainModule {
|
|||
yieldSupplyRepository = yieldSupplyRepository,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideYieldSupplyGetShouldShowMainPromoUseCase(
|
||||
yieldSupplyRepository: YieldSupplyRepository,
|
||||
): YieldSupplyGetShouldShowMainPromoUseCase {
|
||||
return YieldSupplyGetShouldShowMainPromoUseCase(
|
||||
yieldSupplyRepository = yieldSupplyRepository,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideYieldSupplySetShouldShowMainPromoUseCase(
|
||||
yieldSupplyRepository: YieldSupplyRepository,
|
||||
): YieldSupplySetShouldShowMainPromoUseCase {
|
||||
return YieldSupplySetShouldShowMainPromoUseCase(
|
||||
yieldSupplyRepository = yieldSupplyRepository,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideYieldSupplyGetDustMinAmountUseCase(): YieldSupplyGetDustMinAmountUseCase {
|
||||
return YieldSupplyGetDustMinAmountUseCase()
|
||||
}
|
||||
}
|
||||
|
|
@ -114,6 +114,7 @@ internal object UserWalletsListManagerModule {
|
|||
publicInformationRepository = publicInformationRepository,
|
||||
sensitiveInformationRepository = sensitiveInformationRepository,
|
||||
selectedUserWalletRepository = selectedUserWalletRepository,
|
||||
dispatcherProvider = dispatchers,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,11 +16,13 @@ import com.tangem.tap.domain.userWalletList.utils.encryptionKey
|
|||
import com.tangem.tap.domain.userWalletList.utils.lockAll
|
||||
import com.tangem.tap.domain.userWalletList.utils.toUserWallets
|
||||
import com.tangem.tap.domain.userWalletList.utils.updateWith
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import kotlinx.coroutines.withContext
|
||||
import timber.log.Timber
|
||||
|
||||
@Suppress("LargeClass")
|
||||
|
|
@ -30,6 +32,7 @@ internal class BiometricUserWalletsListManager(
|
|||
private val publicInformationRepository: UserWalletsPublicInformationRepository,
|
||||
private val sensitiveInformationRepository: UserWalletsSensitiveInformationRepository,
|
||||
private val selectedUserWalletRepository: SelectedUserWalletRepository,
|
||||
private val dispatcherProvider: CoroutineDispatcherProvider,
|
||||
) : UserWalletsListManager.Lockable {
|
||||
private val state = MutableStateFlow(State())
|
||||
|
||||
|
|
@ -72,12 +75,14 @@ internal class BiometricUserWalletsListManager(
|
|||
return runBlocking {
|
||||
// workaround to avoid calling hasSavedEncryptionKeys many times because of performance
|
||||
savedWalletMutex.withLock {
|
||||
Timber.i("Checking if user has saved wallets")
|
||||
val hasSavedWalletsLocal = hasSavedWallets
|
||||
if (hasSavedWalletsLocal == null || !hasSavedWalletsLocal) {
|
||||
val hasKeys = keysRepository.hasSavedEncryptionKeys()
|
||||
hasSavedWallets = hasKeys
|
||||
hasKeys
|
||||
} else {
|
||||
Timber.i("User has saved wallets (from cache)")
|
||||
true
|
||||
}
|
||||
}
|
||||
|
|
@ -93,23 +98,25 @@ internal class BiometricUserWalletsListManager(
|
|||
.distinctUntilChanged()
|
||||
|
||||
override suspend fun unlock(type: UnlockType): CompletionResult<UserWallet> {
|
||||
return unlockAndSetSelectedUserWallet(type)
|
||||
.mapFailure { error ->
|
||||
Timber.e(error, "Unable to unlock user wallets")
|
||||
if (error is UserWalletsListError) {
|
||||
error
|
||||
} else {
|
||||
UserWalletsListError.UnableToUnlockUserWallets(error)
|
||||
return withContext(dispatcherProvider.io) {
|
||||
unlockAndSetSelectedUserWallet(type)
|
||||
.mapFailure { error ->
|
||||
Timber.e(error, "Unable to unlock user wallets")
|
||||
if (error is UserWalletsListError) {
|
||||
error
|
||||
} else {
|
||||
UserWalletsListError.UnableToUnlockUserWallets(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
.map { selectedUserWallet ->
|
||||
if (selectedUserWallet == null || selectedUserWallet.isLocked) {
|
||||
Timber.e("Unable to find selected user wallet")
|
||||
throw UserWalletsListError.NoUserWalletSelected
|
||||
} else {
|
||||
selectedUserWallet
|
||||
.map { selectedUserWallet ->
|
||||
if (selectedUserWallet == null || selectedUserWallet.isLocked) {
|
||||
Timber.e("Unable to find selected user wallet")
|
||||
throw UserWalletsListError.NoUserWalletSelected
|
||||
} else {
|
||||
selectedUserWallet
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun lock() {
|
||||
|
|
@ -141,18 +148,20 @@ internal class BiometricUserWalletsListManager(
|
|||
}
|
||||
|
||||
override suspend fun save(userWallet: UserWallet, canOverride: Boolean): CompletionResult<Unit> {
|
||||
return if (canOverride) {
|
||||
saveInternal(userWallet, changeSelectedUserWallet = true, canOverridePublicInfo = false)
|
||||
} else {
|
||||
val isWalletSaved = state.value.userWallets
|
||||
.any {
|
||||
it.walletId == userWallet.walletId
|
||||
}
|
||||
|
||||
if (isWalletSaved) {
|
||||
CompletionResult.Failure(UserWalletsListError.WalletAlreadySaved)
|
||||
} else {
|
||||
return withContext(dispatcherProvider.io) {
|
||||
if (canOverride) {
|
||||
saveInternal(userWallet, changeSelectedUserWallet = true, canOverridePublicInfo = false)
|
||||
} else {
|
||||
val isWalletSaved = state.value.userWallets
|
||||
.any {
|
||||
it.walletId == userWallet.walletId
|
||||
}
|
||||
|
||||
if (isWalletSaved) {
|
||||
CompletionResult.Failure(UserWalletsListError.WalletAlreadySaved)
|
||||
} else {
|
||||
saveInternal(userWallet, changeSelectedUserWallet = true, canOverridePublicInfo = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -161,16 +170,18 @@ internal class BiometricUserWalletsListManager(
|
|||
userWalletId: UserWalletId,
|
||||
update: suspend (UserWallet) -> UserWallet,
|
||||
): CompletionResult<UserWallet> {
|
||||
return get(userWalletId)
|
||||
.map { storedUserWallet ->
|
||||
update(storedUserWallet)
|
||||
}
|
||||
.flatMap { updatedUserWallet ->
|
||||
saveInternal(updatedUserWallet, changeSelectedUserWallet = false, canOverridePublicInfo = true)
|
||||
}
|
||||
.flatMap {
|
||||
get(userWalletId)
|
||||
}
|
||||
return withContext(dispatcherProvider.io) {
|
||||
get(userWalletId)
|
||||
.map { storedUserWallet ->
|
||||
update(storedUserWallet)
|
||||
}
|
||||
.flatMap { updatedUserWallet ->
|
||||
saveInternal(updatedUserWallet, changeSelectedUserWallet = false, canOverridePublicInfo = true)
|
||||
}
|
||||
.flatMap {
|
||||
get(userWalletId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun delete(userWalletIds: List<UserWalletId>): CompletionResult<Unit> {
|
||||
|
|
@ -187,44 +198,48 @@ internal class BiometricUserWalletsListManager(
|
|||
return clear()
|
||||
}
|
||||
|
||||
return sensitiveInformationRepository.delete(idsToRemove)
|
||||
.flatMap { publicInformationRepository.delete(idsToRemove) }
|
||||
.map { keysRepository.delete(idsToRemove) }
|
||||
.map {
|
||||
state.update { prevState ->
|
||||
val remainingWallets = prevState.userWallets.filter { it.walletId !in idsToRemove }
|
||||
return withContext(dispatcherProvider.io) {
|
||||
sensitiveInformationRepository.delete(idsToRemove)
|
||||
.flatMap { publicInformationRepository.delete(idsToRemove) }
|
||||
.map { keysRepository.delete(idsToRemove) }
|
||||
.map {
|
||||
state.update { prevState ->
|
||||
val remainingWallets = prevState.userWallets.filter { it.walletId !in idsToRemove }
|
||||
|
||||
val isSelectedWalletDeleted = prevState.selectedUserWalletId in idsToRemove
|
||||
val newSelectedUserWallet = findOrSetSelectedWallet(
|
||||
prevSelectedWalletId = prevState.selectedUserWalletId,
|
||||
prevSelectedWalletIndex = prevState.userWallets.indexOfFirst {
|
||||
it.walletId == prevState.selectedUserWalletId
|
||||
},
|
||||
userWallets = remainingWallets,
|
||||
ignorePrevSelectedWallet = isSelectedWalletDeleted,
|
||||
)
|
||||
val isSelectedWalletDeleted = prevState.selectedUserWalletId in idsToRemove
|
||||
val newSelectedUserWallet = findOrSetSelectedWallet(
|
||||
prevSelectedWalletId = prevState.selectedUserWalletId,
|
||||
prevSelectedWalletIndex = prevState.userWallets.indexOfFirst {
|
||||
it.walletId == prevState.selectedUserWalletId
|
||||
},
|
||||
userWallets = remainingWallets,
|
||||
ignorePrevSelectedWallet = isSelectedWalletDeleted,
|
||||
)
|
||||
|
||||
prevState.copy(
|
||||
encryptionKeys = prevState.encryptionKeys.filter { it.walletId !in idsToRemove },
|
||||
userWallets = remainingWallets,
|
||||
isLocked = remainingWallets.any { it.isLocked },
|
||||
selectedUserWalletId = newSelectedUserWallet?.walletId,
|
||||
)
|
||||
prevState.copy(
|
||||
encryptionKeys = prevState.encryptionKeys.filter { it.walletId !in idsToRemove },
|
||||
userWallets = remainingWallets,
|
||||
isLocked = remainingWallets.any { it.isLocked },
|
||||
selectedUserWalletId = newSelectedUserWallet?.walletId,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun clear(): CompletionResult<Unit> {
|
||||
savedWalletMutex.withLock {
|
||||
hasSavedWallets = null
|
||||
}
|
||||
return sensitiveInformationRepository.clear()
|
||||
.flatMap { publicInformationRepository.clear() }
|
||||
.map {
|
||||
keysRepository.clear()
|
||||
selectedUserWalletRepository.set(null)
|
||||
state.value = State()
|
||||
}
|
||||
return withContext(dispatcherProvider.io) {
|
||||
sensitiveInformationRepository.clear()
|
||||
.flatMap { publicInformationRepository.clear() }
|
||||
.map {
|
||||
keysRepository.clear()
|
||||
selectedUserWalletRepository.set(null)
|
||||
state.value = State()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun get(userWalletId: UserWalletId): CompletionResult<UserWallet> {
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ internal fun RootContent(
|
|||
startActivity(context, instance.intent, Bundle.EMPTY)
|
||||
}
|
||||
}
|
||||
RoutingComponent.Child.DummyComponent -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ internal interface RoutingComponent : ComposableContentComponent {
|
|||
data class ComposableComponent(
|
||||
val component: ComposableContentComponent,
|
||||
) : Child()
|
||||
|
||||
data object DummyComponent : Child()
|
||||
}
|
||||
|
||||
interface Factory {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import androidx.compose.runtime.Composable
|
|||
import androidx.compose.ui.Modifier
|
||||
import com.arkivanov.decompose.router.stack.ChildStack
|
||||
import com.arkivanov.decompose.router.stack.childStack
|
||||
import com.arkivanov.decompose.router.stack.pop
|
||||
import com.arkivanov.decompose.value.Value
|
||||
import com.arkivanov.decompose.value.subscribe
|
||||
import com.arkivanov.essenty.lifecycle.subscribe
|
||||
|
|
@ -11,7 +12,9 @@ import com.google.android.material.snackbar.Snackbar
|
|||
import com.tangem.common.routing.AppRoute
|
||||
import com.tangem.common.routing.entity.InitScreenLaunchMode
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.core.analytics.api.AnalyticsExceptionHandler
|
||||
import com.tangem.core.analytics.models.Basic
|
||||
import com.tangem.core.analytics.models.ExceptionAnalyticsEvent
|
||||
import com.tangem.core.analytics.utils.TrackingContextProxy
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.decompose.context.child
|
||||
|
|
@ -46,6 +49,7 @@ import dagger.assisted.Assisted
|
|||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
internal class DefaultRoutingComponent @AssistedInject constructor(
|
||||
|
|
@ -66,6 +70,7 @@ internal class DefaultRoutingComponent @AssistedInject constructor(
|
|||
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
private val trackingContextProxy: TrackingContextProxy,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
private val analyticsExceptionHandler: AnalyticsExceptionHandler,
|
||||
) : RoutingComponent,
|
||||
AppComponentContext by context,
|
||||
SnackbarHandler {
|
||||
|
|
@ -80,13 +85,23 @@ internal class DefaultRoutingComponent @AssistedInject constructor(
|
|||
.create(child("hotAccessCodeRequestComponent"), Unit)
|
||||
}
|
||||
|
||||
private val navigation = navigationProvider.getOrCreateTyped<AppRoute>()
|
||||
|
||||
private val stack: Value<ChildStack<AppRoute, Child>> = childStack(
|
||||
source = navigationProvider.getOrCreateTyped(),
|
||||
source = navigation,
|
||||
initialStack = { getInitialStackOrInit() },
|
||||
serializer = null, // AppRoute.serializer(), // Disabled until Nav refactoring completes
|
||||
handleBackButton = true,
|
||||
childFactory = { route, childContext ->
|
||||
childFactory.createChild(route, childByContext(childContext))
|
||||
try {
|
||||
childFactory.createChild(route, childByContext(childContext))
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e, "App Router Failed")
|
||||
analyticsExceptionHandler.sendException(
|
||||
ExceptionAnalyticsEvent(exception = e, params = mapOf("Category" to "App Routing")),
|
||||
)
|
||||
Child.DummyComponent
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
|
@ -96,6 +111,12 @@ internal class DefaultRoutingComponent @AssistedInject constructor(
|
|||
appRouterConfig.snackbarHandler = this
|
||||
|
||||
stack.subscribe(lifecycle) { stack ->
|
||||
// Handle DummyComponent by popping it immediately
|
||||
if (stack.active.instance is Child.DummyComponent) {
|
||||
navigation.pop()
|
||||
return@subscribe
|
||||
}
|
||||
|
||||
val stackItems = stack.items.map { it.configuration }
|
||||
|
||||
wcRoutingComponent.onAppRouteChange(stack.active.configuration)
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ internal class BiometricUserWalletsListManagerTest(private val model: Model) {
|
|||
publicInformationRepository = mockk(),
|
||||
sensitiveInformationRepository = mockk(),
|
||||
selectedUserWalletRepository = mockk(),
|
||||
dispatcherProvider = mockk(),
|
||||
)
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -43,12 +43,14 @@ import java.math.BigDecimal
|
|||
*/
|
||||
class TokenItemStateConverter(
|
||||
private val appCurrency: AppCurrency,
|
||||
private val yieldModuleApyMap: Map<String, String> = emptyMap(),
|
||||
private val yieldModuleApyMap: Map<String, BigDecimal> = emptyMap(),
|
||||
private val stakingApyMap: Map<String, List<Yield.Validator>> = emptyMap(),
|
||||
private val yieldSupplyPromoBannerKey: String? = null,
|
||||
private val iconStateProvider: (CryptoCurrencyStatus) -> CurrencyIconState = {
|
||||
CryptoCurrencyToIconStateConverter().convert(it)
|
||||
},
|
||||
private val onApyLabelClick: ((CryptoCurrencyStatus, ApySource, String) -> Unit)? = null,
|
||||
private val onYieldPromoCloseClick: (() -> Unit)? = null,
|
||||
private val titleStateProvider: (CryptoCurrencyStatus) -> TokenItemState.TitleState = { currencyStatus ->
|
||||
createTitleState(
|
||||
currencyStatus = currencyStatus,
|
||||
|
|
@ -66,6 +68,15 @@ class TokenItemStateConverter(
|
|||
private val fiatAmountStateProvider: (CryptoCurrencyStatus) -> TokenItemState.FiatAmountState? = {
|
||||
createFiatAmountState(status = it, appCurrency = appCurrency)
|
||||
},
|
||||
private val promoBannerProvider: (CryptoCurrencyStatus) -> TokenItemState.PromoBannerState = { status ->
|
||||
createPromoBannerState(
|
||||
status = status,
|
||||
yieldModuleApyMap = yieldModuleApyMap,
|
||||
yieldSupplyPromoBannerKey = yieldSupplyPromoBannerKey,
|
||||
onApyLabelClick = onApyLabelClick,
|
||||
onYieldPromoCloseClick = onYieldPromoCloseClick,
|
||||
)
|
||||
},
|
||||
private val onItemClick: ((TokenItemState, CryptoCurrencyStatus) -> Unit)? = null,
|
||||
private val onItemLongClick: ((TokenItemState, CryptoCurrencyStatus) -> Unit)? = null,
|
||||
) : Converter<CryptoCurrencyStatus, TokenItemState> {
|
||||
|
|
@ -102,6 +113,7 @@ class TokenItemStateConverter(
|
|||
subtitleState = requireNotNull(subtitleStateProvider(this)),
|
||||
fiatAmountState = requireNotNull(fiatAmountStateProvider(this)),
|
||||
subtitle2State = requireNotNull(subtitle2StateProvider(this)),
|
||||
promoBannerState = promoBannerProvider(this),
|
||||
onItemClick = onItemClick?.let { onItemClick ->
|
||||
{ onItemClick(it, this) }
|
||||
},
|
||||
|
|
@ -164,7 +176,7 @@ class TokenItemStateConverter(
|
|||
|
||||
private fun createTitleState(
|
||||
currencyStatus: CryptoCurrencyStatus,
|
||||
yieldModuleApyMap: Map<String, String>,
|
||||
yieldModuleApyMap: Map<String, BigDecimal>,
|
||||
stakingApyMap: Map<String, List<Yield.Validator>>,
|
||||
onApyLabelClick: ((CryptoCurrencyStatus, ApySource, String) -> Unit)?,
|
||||
): TokenItemState.TitleState {
|
||||
|
|
@ -204,7 +216,7 @@ class TokenItemStateConverter(
|
|||
// polygon-pos_0xc2132d05d31c914a87c6611c10748aeb04b58e8f
|
||||
private fun resolveEarnApy(
|
||||
cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
yieldModuleApyMap: Map<String, String>,
|
||||
yieldModuleApyMap: Map<String, BigDecimal>,
|
||||
stakingApyMap: Map<String, List<Yield.Validator>>,
|
||||
): EarnApyInfo? {
|
||||
val token = cryptoCurrencyStatus.currency as? CryptoCurrency.Token
|
||||
|
|
@ -223,7 +235,7 @@ class TokenItemStateConverter(
|
|||
wrappedList(yieldSupplyApy),
|
||||
),
|
||||
isActive = isActive,
|
||||
apy = yieldSupplyApy,
|
||||
apy = yieldSupplyApy.toString(),
|
||||
source = ApySource.YIELD_SUPPLY,
|
||||
)
|
||||
}
|
||||
|
|
@ -384,6 +396,36 @@ class TokenItemStateConverter(
|
|||
}
|
||||
}
|
||||
|
||||
private fun createPromoBannerState(
|
||||
status: CryptoCurrencyStatus,
|
||||
yieldModuleApyMap: Map<String, BigDecimal>,
|
||||
yieldSupplyPromoBannerKey: String?,
|
||||
onApyLabelClick: ((CryptoCurrencyStatus, ApySource, String) -> Unit)?,
|
||||
onYieldPromoCloseClick: (() -> Unit)?,
|
||||
): TokenItemState.PromoBannerState {
|
||||
val token = status.currency as? CryptoCurrency.Token ?: return TokenItemState.PromoBannerState.Empty
|
||||
if (yieldSupplyPromoBannerKey == null || yieldSupplyPromoBannerKey != token.yieldSupplyKey() ||
|
||||
yieldModuleApyMap[token.yieldSupplyKey()] == null
|
||||
) {
|
||||
return TokenItemState.PromoBannerState.Empty
|
||||
}
|
||||
val yieldSupplyApy =
|
||||
yieldModuleApyMap[token.yieldSupplyKey()] ?: return TokenItemState.PromoBannerState.Empty
|
||||
|
||||
return TokenItemState.PromoBannerState.Content(
|
||||
title = resourceReference(
|
||||
R.string.yield_module_main_screen_promo_banner_message,
|
||||
wrappedList(yieldSupplyApy),
|
||||
),
|
||||
onPromoBannerClick = {
|
||||
onApyLabelClick?.invoke(status, ApySource.YIELD_SUPPLY, yieldSupplyApy.toString())
|
||||
},
|
||||
onCloseClick = {
|
||||
onYieldPromoCloseClick?.invoke()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private fun CryptoCurrencyStatus.getCryptoPriceState(appCurrency: AppCurrency): TokenItemState.SubtitleState {
|
||||
val fiatRate = value.fiatRate
|
||||
val priceChange = value.priceChange
|
||||
|
|
|
|||
|
|
@ -122,6 +122,10 @@ object PreferencesKeys {
|
|||
|
||||
val YIELD_SUPPLY_WARNINGS_STATES_KEY by lazy { stringPreferencesKey(name = "yieldSupplyWarningsStates") }
|
||||
|
||||
val YIELD_SUPPLY_SHOULD_SHOW_MAIN_PROMO_KEY by lazy {
|
||||
booleanPreferencesKey(name = "yieldSupplyShouldShowMainPromo")
|
||||
}
|
||||
|
||||
val ACCESS_CODE_SKIPPED_STATES_KEY by lazy { stringPreferencesKey(name = "accessCodeSkippedStates") }
|
||||
|
||||
// region Notifications
|
||||
|
|
@ -179,6 +183,12 @@ object PreferencesKeys {
|
|||
fun getTangemPayAddToWalletKey(customerWalletAddress: String) =
|
||||
booleanPreferencesKey("tangem_pay_add_to_wallet_done_key_$customerWalletAddress")
|
||||
|
||||
fun getTangemPayOrderIdKey(customerWalletAddress: String) =
|
||||
stringPreferencesKey("tangem_pay_order_id_key_$customerWalletAddress")
|
||||
|
||||
fun getTangemPayCustomerWalletAddressKey(userWalletId: UserWalletId) =
|
||||
stringPreferencesKey("tangem_pay_customer_wallet_address_key_${userWalletId.stringValue}")
|
||||
|
||||
fun getTangemPayCheckCustomerByWalletId(userWalletId: UserWalletId) =
|
||||
booleanPreferencesKey("tangem_pay_check_customer_by_wallet_id_$userWalletId")
|
||||
|
||||
|
|
|
|||
|
|
@ -44,7 +44,12 @@ class NetworkLogsSaveInterceptor(
|
|||
throw e
|
||||
}
|
||||
|
||||
if (restrictedForLogURLs.contains(request.url.host + request.url.encodedPath)) {
|
||||
val host = request.url.host
|
||||
val path = request.url.encodedPath
|
||||
val isRestrictedUrl = restrictedForLogURLs.contains(host + path)
|
||||
val isRestrictedHost = restrictedForLogHosts.any { host.contains(it) }
|
||||
|
||||
if (isRestrictedUrl || isRestrictedHost) {
|
||||
logResponseWithEmptyMessage(response, startNs)
|
||||
} else {
|
||||
logResponseMessage(response, startNs)
|
||||
|
|
@ -222,5 +227,8 @@ class NetworkLogsSaveInterceptor(
|
|||
val restrictedForLogURLs = listOf(
|
||||
"api.stakek.it/v1/yields/enabled",
|
||||
)
|
||||
val restrictedForLogHosts = listOf(
|
||||
"us.paera.com",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -3,10 +3,14 @@
|
|||
<string name="access_code_alert_skip_description">Ohne Zugangscode ist Deine Wallet nicht geschützt.</string>
|
||||
<string name="access_code_alert_skip_ok">Trotzdem überspringen</string>
|
||||
<string name="access_code_alert_skip_title">Zugangscode nicht festgelegt</string>
|
||||
<string name="access_code_alert_validation_cancel">Code ändern</string>
|
||||
<string name="access_code_alert_validation_description">Dein Zugangscode dient zum Entsperren Deiner Wallet und zum Schutz des Zugriffs auf Deine Vermögenswerte.</string>
|
||||
<string name="access_code_alert_validation_ok">Trotzdem verwenden</string>
|
||||
<string name="access_code_alert_validation_title">Dieser Zugangscode kann leicht erraten werden</string>
|
||||
<string name="access_code_check_title">Zugangscode eingeben</string>
|
||||
<string name="access_code_check_warining_delete">Falscher Zugangscode. Deine mobile Wallet wird nach %s weiteren Fehlversuchen gelöscht.</string>
|
||||
<string name="access_code_check_warining_lock">Falscher Zugangscode. Die App wird nach %s weiteren Fehlversuchen gesperrt.</string>
|
||||
<string name="access_code_check_warining_wait">Falscher Zugangscode.\nBitte warte %s Sekunden und versuche es erneut.</string>
|
||||
<string name="access_code_check_warining_wait">Falscher Zugangscode.\n Bitte warte %s Sekunden und versuche es erneut.</string>
|
||||
<string name="access_code_confirm_description">Bestätige Deinen Zugangscode, um fortzufahren.</string>
|
||||
<string name="access_code_confirm_title">Zugangscode erneut eingeben</string>
|
||||
<string name="access_code_create_description">Erstelle einen %s-stelliger Zugangscode, um Deine Wallet zu entsperren.</string>
|
||||
|
|
@ -32,6 +36,7 @@
|
|||
<string name="account_details_archive_description">Du archivierst dieses Konto, kannst es aber jederzeit entarchivieren.</string>
|
||||
<string name="account_details_archiving">Archivierung...</string>
|
||||
<string name="account_details_title">Konto</string>
|
||||
<string name="account_edit_failure_dialog_title">Ich kann das Konto nicht bearbeiten.</string>
|
||||
<string name="account_edit_success_message">Konto gespeichert</string>
|
||||
<string name="account_for_rewards">Prämien berücksichtigen</string>
|
||||
<string name="account_form_account_index">Kontonummer %s – wird zur Adressableitung verwendet.</string>
|
||||
|
|
@ -139,10 +144,17 @@
|
|||
<string name="balance_hidden_title">Guthaben sind ausgeblendet</string>
|
||||
<string name="beta_mode_warning_message">Laut den Blockchain-Entwicklern befinden sich der Kaspa-Token derzeit in der Betaphase. Bleibe dran für Updates!</string>
|
||||
<string name="beta_mode_warning_title">Beta-Phase</string>
|
||||
<string name="biometric_disabled_warning_description">Die biometrischen Daten sind auf Deinem Gerät deaktiviert, sodass Du sie nicht zum Entsperren Deine Wallet verwenden kannst. Aktiviere die Biometrie in den Einstellungen Deines Geräts, um diese Methode wieder zu verwenden.</string>
|
||||
<string name="biometric_disabled_warning_title">Biometrische Authentifizierung deaktiviert</string>
|
||||
<string name="biometric_lockout_permanent_warning_description">Bitte Karte oder Ring scannen</string>
|
||||
<string name="biometric_lockout_permanent_warning_description_2">Du hast das Limit an biometrischen Entsperrversuchen erreicht. Bitte entsperren Deine Wallet durch Antippen Deines Geräts oder gib den Zugangscode ein.</string>
|
||||
<string name="biometric_lockout_permanent_warning_title">Biometrische Authentifizierung gesperrt</string>
|
||||
<string name="biometric_lockout_warning_description">Bitte versuche es in 30 Sekunden erneut oder scanne die Karte oder Ring</string>
|
||||
<string name="biometric_lockout_warning_description_2">Die biometrische Anmeldung ist vorübergehend gesperrt. Bitte versuche es in 30 Sekunden erneut oder entsperre Deine Wallet durch Antippen Deines Geräts oder mit einem Zugangscode.</string>
|
||||
<string name="biometric_lockout_warning_title">Zu viele Versuche</string>
|
||||
<string name="biometric_unavailable_warning">Du hast die biometrische Authentifizierung auf deinem Telefon deaktiviert und kannst keine Wallets in der App speichern. Um Wallets zu speichern, aktiviere bitte die biometrische Authentifizierung in deinen Telefoneinstellungen.</string>
|
||||
<string name="biometric_updated_warning_description">Die biometrischen Daten Deines Geräts wurden aktualisiert. Bitte wähle Deine Wallet aus und gib den zugehörigen Zugangscode ein, um die biometrische Anmeldung wieder zu aktivieren.</string>
|
||||
<string name="biometric_updated_warning_title">Aufmerksamkeit erforderlich</string>
|
||||
<string name="bitcoin_promo_activation_error">Bei der Bearbeitung Deines Aktionscodes ist ein Fehler aufgetreten. Bitte versuche es später noch einmal.</string>
|
||||
<string name="bitcoin_promo_activation_error_title">Fehler bei der Aktivierung</string>
|
||||
<string name="bitcoin_promo_activation_success">Dein Gutscheincode wurde erfolgreich aktiviert. Die Prämie wird deinem Bitcoin-Konto innerhalb von 14 Tagen gutgeschrieben.</string>
|
||||
|
|
@ -221,7 +233,7 @@
|
|||
<string name="common_build_tx_error">Transaktion fehlgeschlagen</string>
|
||||
<string name="common_buy">Kaufen</string>
|
||||
<string name="common_buy_currency">Gehe zu %1$s</string>
|
||||
<string name="common_camera_denied_alert_message">D hast keinen Zugang zur Kamera erteilt, bitte passe deine Datenschutzeinstellungen an</string>
|
||||
<string name="common_camera_denied_alert_message">Du hast keinen Zugang zur Kamera erteilt, bitte passe Deine Datenschutzeinstellungen an</string>
|
||||
<string name="common_cancel">Abbrechen</string>
|
||||
<string name="common_change">Ändern</string>
|
||||
<string name="common_choose_account">Konto auswählen</string>
|
||||
|
|
@ -235,6 +247,7 @@
|
|||
<string name="common_coming_soon">Demnächst verfügbar</string>
|
||||
<string name="common_confirm">Bestätigen</string>
|
||||
<string name="common_connecting">Verbinden</string>
|
||||
<string name="common_contact_support">Kontakt zum Support</string>
|
||||
<string name="common_contact_tangem_support">Kontakt zum Tangem-Support</string>
|
||||
<string name="common_contact_visa_support">Kontakt zum Visa-Support</string>
|
||||
<string name="common_continue">Weiter</string>
|
||||
|
|
@ -284,7 +297,7 @@
|
|||
<string name="common_go_to_token">Zum Token</string>
|
||||
<string name="common_got_it">Verstanden</string>
|
||||
<string name="common_hide">Ausblenden</string>
|
||||
<string name="common_hour">stunde</string>
|
||||
<string name="common_hour">Stunde</string>
|
||||
<string name="common_import">Importieren</string>
|
||||
<string name="common_in_progress">In Arbeit</string>
|
||||
<string name="common_later">Später</string>
|
||||
|
|
@ -294,7 +307,7 @@
|
|||
<string name="common_locked">Gesperrt</string>
|
||||
<string name="common_locked_wallets">Gesperrte Wallet</string>
|
||||
<string name="common_main_network">Hauptnetz</string>
|
||||
<string name="common_month">monat</string>
|
||||
<string name="common_month">Monat</string>
|
||||
<string name="common_network_fee_title">Netzgebühr</string>
|
||||
<string name="common_network_fee_warning_content">Der überwiesene Betrag wird um %1$s (%2$s) gekürzt, um die gewählte Gebührenhöhe zu decken.</string>
|
||||
<plurals name="common_networks_count">
|
||||
|
|
@ -376,7 +389,7 @@
|
|||
<string name="common_unstake">Staking beenden</string>
|
||||
<string name="common_utxo_validate_withdrawal_message_warning">Aufgrund der Beschränkungen von %1$s können nur %2$d UTXOs in eine einzige Transaktion passen. Das bedeutet, dass du nur %3$s oder weniger senden kannst. Du musst den Betrag reduzieren.</string>
|
||||
<string name="common_value_copied">Wert kopiert</string>
|
||||
<string name="common_week">woche</string>
|
||||
<string name="common_week">Woche</string>
|
||||
<string name="common_with">mit</string>
|
||||
<string name="common_yes">Ja</string>
|
||||
<string name="contract_address_copied_message">Vertragsadresse kopiert!</string>
|
||||
|
|
@ -423,7 +436,6 @@
|
|||
<string name="details_row_description_flip_to_hide">Flippe den Bildschirm deines Geräts nach unten, um Salden schnell ein- und auszublenden</string>
|
||||
<string name="details_row_subtitle_signed_hashes_format">%s Hasch</string>
|
||||
<string name="details_row_title_cid">Geräte-ID</string>
|
||||
<string name="details_row_title_contact_to_support">Kontakt zum Support</string>
|
||||
<string name="details_row_title_contact_to_support_chat">Support-Chat öffnen</string>
|
||||
<string name="details_row_title_create_backup">Weitere Karten oder Ringe verknüpfen</string>
|
||||
<string name="details_row_title_currency">App Währung</string>
|
||||
|
|
@ -557,7 +569,7 @@
|
|||
<string name="home_button_create_new_wallet">Neues Wallet erstellen</string>
|
||||
<string name="home_button_order">Karte oder Ring bestellen</string>
|
||||
<string name="home_button_scan">Karte oder Ring scannen</string>
|
||||
<string name="hot_access_code_set_biometric_ask">Möchtest Du „Tangem“ die biometrische Authentifizierung erlauben? Um Deine Identität zu bestätigen und die App zu öffnen</string>
|
||||
<string name="hot_access_code_set_biometric_ask">Möchtest Du „Tangem“ die Verwendung biometrischer Authentifizierung erlauben? Um Deine Identität zu bestätigen und die App zu öffnen, klicke bitte hier.</string>
|
||||
<string name="hot_crypto_add_token_subtitle">An %s</string>
|
||||
<string name="hot_crypto_token_network">Im %s Netzwerk</string>
|
||||
<string name="hw_access_code_create_alert_title">Willst Du den Vorgang zur Erstellung des Zugangscodes wirklich beenden?</string>
|
||||
|
|
@ -583,7 +595,6 @@
|
|||
<string name="hw_backup_need_title">Zuerst die Sicherung abschließen</string>
|
||||
<string name="hw_backup_no_backup">Unvollständig</string>
|
||||
<string name="hw_backup_section_other_title">Andere Methoden</string>
|
||||
<string name="hw_backup_seed_description">Physische Geräte, die Deine privaten Schlüssel sicher offline speichern.</string>
|
||||
<string name="hw_backup_seed_title">Wiederherstellungs-Phrase</string>
|
||||
<string name="hw_backup_to_upgrade_description">Um Deine Wallet auf Hardware umzustellen, erstelle vorher ein Backup.</string>
|
||||
<string name="hw_create_keys_description">Deine privaten Schlüssel sind sicher verschlüsselt und auf Deinem Telefon gespeichert.</string>
|
||||
|
|
@ -679,11 +690,13 @@
|
|||
<string name="markets_apy_placeholder">APY %s</string>
|
||||
<string name="markets_common_my_portfolio">Mein Portfolio</string>
|
||||
<string name="markets_common_title">Markt</string>
|
||||
<string name="markets_earn_common_title">Verdiene Geld mit Tangem</string>
|
||||
<string name="markets_generate_addresses_notification">Um Adressen für ausgewählte Netzwerke zu generieren, musst du eine Tangem-Karte oder Ring scannen</string>
|
||||
<string name="markets_hint">Um Token hinzuzufügen, rufe dies auf oder tippe auf die Suchleiste</string>
|
||||
<string name="markets_insights_info_description_message">Die Daten dieses Abschnitts stammen aus den folgenden Netzwerken: %s</string>
|
||||
<string name="markets_loading_error_title">Die Daten konnten nicht geladen werden...</string>
|
||||
<string name="markets_loading_no_data_title">Keine Daten</string>
|
||||
<string name="markets_pulse_common_title">Marktimpuls</string>
|
||||
<string name="markets_quick_actions">Schnelle Aktionen</string>
|
||||
<string name="markets_search_header_title">Markt durchsuchen</string>
|
||||
<string name="markets_search_result_title">Ergebnis</string>
|
||||
|
|
@ -774,6 +787,10 @@
|
|||
<string name="markets_token_details_volume">Volumen</string>
|
||||
<string name="markets_tooltip_message">Rufe dies auf oder tippe auf die Suchleiste, um Token direkt vom Markt hinzuzufügen</string>
|
||||
<string name="markets_tooltip_title">Token hinzufügen</string>
|
||||
<string name="markets_yield_supply_banner_description">Steiger die Leistung Deiner Assets und ermögliche Dir gleichzeitig den sofortigen Zugriff. %s</string>
|
||||
<string name="markets_yield_supply_banner_title">Yield-Modus aktivieren</string>
|
||||
<string name="mobile_wallet_requires_min_os_warning_body">Du musst auf die folgende Version aktualisieren: %1$s um eine mobile Wallet zu erstellen</string>
|
||||
<string name="mobile_wallet_requires_min_os_warning_title">Mobile Wallet erfordert %1$s oder später</string>
|
||||
<string name="news_all_news">Alle Neuigkeiten</string>
|
||||
<string name="news_stay_in_the_loop">Auf dem Laufenden bleiben</string>
|
||||
<string name="nfc_error_unavailable">NFC ist auf deinem Gerät nicht verfügbar</string>
|
||||
|
|
@ -1368,31 +1385,45 @@
|
|||
<string name="swapping_to_title">Du erhältst</string>
|
||||
<string name="swapping_token_list_title">Token auswählen</string>
|
||||
<string name="swapping_token_not_available">Nicht verfügbar</string>
|
||||
<string name="tangem_pay_beta_notification_subtitle">Wir freuen uns über Ihr Feedback</string>
|
||||
<string name="tangem_pay_beta_notification_title">Tangem Pay jetzt in der Beta</string>
|
||||
<string name="tangem_pay_card_frozen">Karte eingefroren</string>
|
||||
<string name="tangem_pay_card_payment">Kartenzahlung</string>
|
||||
<string name="tangem_pay_deposit">Einzahlung</string>
|
||||
<string name="tangem_pay_dispute">Streitfall</string>
|
||||
<string name="tangem_pay_explore_transaction">Transaktion erkunden</string>
|
||||
<string name="tangem_pay_fee_subtitle">Servicegebühren</string>
|
||||
<string name="tangem_pay_fee_title">Gebühr</string>
|
||||
<string name="tangem_pay_freeze_card_alert_body">Schütze Dein Geld, falls Deine Karte verloren geht oder gestohlen wird. Du kannst die Sperre jederzeit aufheben.</string>
|
||||
<string name="tangem_pay_freeze_card_alert_body">Schütze Dein Geld. Du kannst die Sperre jederzeit aufheben.</string>
|
||||
<string name="tangem_pay_freeze_card_alert_title">Karte sperren lassen?</string>
|
||||
<string name="tangem_pay_freeze_card_failed">Karte konnte nicht eingefroren werden. Versuchen Sie es später erneut.</string>
|
||||
<string name="tangem_pay_freeze_card_freeze">Einfrieren</string>
|
||||
<string name="tangem_pay_freeze_card_success">Ihre Karte ist eingefroren.</string>
|
||||
<string name="tangem_pay_get_help">Hilfe erhalten</string>
|
||||
<string name="tangem_pay_other">Andere</string>
|
||||
<string name="tangem_pay_status_completed">Abgeschlossen</string>
|
||||
<string name="tangem_pay_status_declined">Abgelehnt</string>
|
||||
<string name="tangem_pay_status_pending">Ausstehend</string>
|
||||
<string name="tangem_pay_terms_fees_limits">Bedingungen, Gebühren & Limits</string>
|
||||
<string name="tangem_pay_terms_limits">Bedingungen und Einschränkungen</string>
|
||||
<string name="tangem_pay_transaction_declined_notification_text">Die Bank hat diese Transaktionsanfrage abgelehnt.</string>
|
||||
<string name="tangem_pay_transaction_fee_notification_text">Diese Gebühr dient zur Deckung der Kosten für die Abwicklung Deiner Überweisung.</string>
|
||||
<string name="tangem_pay_transaction_fee_notification_text">Diese Gebühr dient zur Deckung der Kosten für die Abwicklung Deiner Überweisung.Questa commissione copre il costo della gestione del tuo trasferimento.</string>
|
||||
<string name="tangem_pay_unfreeze_card_alert_body">Nutze Dein Geld weiterhin. Du kannst es jederzeit einfrieren.</string>
|
||||
<string name="tangem_pay_unfreeze_card_alert_title">Karte entsperren?</string>
|
||||
<string name="tangem_pay_unfreeze_card_failed">Entsperren der Karte fehlgeschlagen. Versuchen Sie es später erneut.</string>
|
||||
<string name="tangem_pay_unfreeze_card_success">Ihre Karte ist entsperrt.</string>
|
||||
<string name="tangem_pay_withdrawal">Abhebung</string>
|
||||
<string name="tangempay_card_details_add_funds">Guthaben hinzufügen</string>
|
||||
<string name="tangempay_card_details_add_funds_subtitle">Aufladeoptionen</string>
|
||||
<string name="tangempay_card_details_card_number">Kartennummer</string>
|
||||
<string name="tangempay_card_details_change_pin">PIN ändern</string>
|
||||
<string name="tangempay_card_details_change_pin_success_description">Die Karte ist vollständig für Zahlungen bereit.</string>
|
||||
<string name="tangempay_card_details_change_pin_success_title">PIN-Code erstellt</string>
|
||||
<string name="tangempay_card_details_cvc">CVC</string>
|
||||
<string name="tangempay_card_details_error_text">Daten konnten nicht geladen werden. Versuche es später noch einmal.</string>
|
||||
<string name="tangempay_card_details_expiry">Ablaufdatum</string>
|
||||
<string name="tangempay_card_details_freeze_card">Karte einfrieren</string>
|
||||
<string name="tangempay_card_details_hide_details">Details ausblenden</string>
|
||||
<string name="tangempay_card_details_hide_text">Verstecken</string>
|
||||
<string name="tangempay_card_details_open_wallet_button">Google Wallet öffnen</string>
|
||||
<string name="tangempay_card_details_open_wallet_notification_subtitle">Richte Tangem Pay mit wenigen Klicks ein und bezahlen mit Google Pay.</string>
|
||||
|
|
@ -1400,8 +1431,10 @@
|
|||
<string name="tangempay_card_details_open_wallet_notification_title">Karte zu Google Pay hinzufügen</string>
|
||||
<string name="tangempay_card_details_open_wallet_notification_title_apple">Karte zu Apple Pay hinzufügen</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_1">Google Wallet öffnen</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_1_5_apple">Tippen Sie auf die Schaltfläche \"+\" oben rechts</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_1_apple">Apple Wallet öffnen</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_2">Tippe auf „Karte hinzufügen“.</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_2_apple">Tippen Sie auf „Debit- oder Kreditkarte“</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_3">Gebe die Kartendaten manuell ein</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_4">Verifiziere die Karte mit dem Einmalpasswort (OPT), das an Dein Gerät gesendet wird.</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_5">Alles erledigt! Deine Karte ist einsatzbereit.</string>
|
||||
|
|
@ -1411,22 +1444,53 @@
|
|||
<string name="tangempay_card_details_receive_error_description">Es wurden technische Probleme festgestellt. Bitte versuche es später erneut oder kontaktiere den Support.</string>
|
||||
<string name="tangempay_card_details_receive_error_title">Empfangen ist jetzt nicht verfügbar</string>
|
||||
<string name="tangempay_card_details_reveal_text">Aufdecken</string>
|
||||
<string name="tangempay_card_details_show_details">Details anzeigen</string>
|
||||
<string name="tangempay_card_details_swap_description">Tausche beliebige Vermögenswerte in Deinem Portfolio gegen eine Karte.</string>
|
||||
<string name="tangempay_card_details_title">Kartendetails</string>
|
||||
<string name="tangempay_card_details_unfreeze_card">Karte entsperren</string>
|
||||
<string name="tangempay_card_details_withdraw">Auszahlung</string>
|
||||
<string name="tangempay_card_details_withdraw_error_title">Auszahlung derzeit nicht möglich</string>
|
||||
<string name="tangempay_card_details_withdraw_in_progress_description">Sie können keinen Tausch oder eine neue Auszahlung starten, bis die aktuelle abgeschlossen ist.</string>
|
||||
<string name="tangempay_card_details_withdraw_in_progress_title">Auszahlung läuft</string>
|
||||
<string name="tangempay_change_pin_code">PIN-Code ändern</string>
|
||||
<string name="tangempay_come_back_if_forget_pin">Kehren Sie zur App zurück, falls Sie ihn vergessen.</string>
|
||||
<string name="tangempay_failed_to_issue_card">Kartenausstellung fehlgeschlagen</string>
|
||||
<string name="tangempay_failed_to_issue_card_retry_description">Ein technischer Fehler ist aufgetreten, bitte versuchen Sie es erneut, indem Sie auf die Schaltfläche unten klicken</string>
|
||||
<string name="tangempay_failed_to_issue_card_support_description">Ein technischer Fehler ist aufgetreten, bitte kontaktieren Sie den Support</string>
|
||||
<string name="tangempay_get_banner_description">Nutzen Sie Ihre Kryptowährungen für Einkäufe im Alltag. \nEine Zahlungskarte, die ihresgleichen sucht.</string>
|
||||
<string name="tangempay_get_tangem_pay">Tangem Pay erhalten</string>
|
||||
<string name="tangempay_go_to_support">Zum Support</string>
|
||||
<string name="tangempay_issue_card_notification_description">Es dauert in der Regel bis zu 15 Minuten.</string>
|
||||
<string name="tangempay_issue_card_notification_title">Einrichtung Ihrer Tangem-Karte</string>
|
||||
<string name="tangempay_issuing_your_card">Ausstellung Deiner Karte</string>
|
||||
<string name="tangempay_issuing_your_card_description">Wir bereiten Ihre Karte vor. Dies kann etwas dauern.</string>
|
||||
<string name="tangempay_kyc_card_ready_notification_title">Tangem Pay</string>
|
||||
<string name="tangempay_kyc_failed_description">Wir konnten Ihr Profil nicht verifizieren. Bei Fragen wenden Sie sich bitte an den Support.</string>
|
||||
<string name="tangempay_kyc_failed_title">Leider konnten wir Ihre Identität nicht verifizieren</string>
|
||||
<string name="tangempay_kyc_in_progress">KYC in Bearbeitung</string>
|
||||
<string name="tangempay_kyc_in_progress_notification_button">Status anzeigen</string>
|
||||
<string name="tangempay_kyc_in_progress_notification_title">KYC für Tangem Pay in Arbeit</string>
|
||||
<string name="tangempay_onboarding_banner_description">Nutzen Sie Ihre Kryptowährungen für Einkäufe im echten Leben. \nEs ist eine Zahlungskarte, die ihresgleichen sucht.</string>
|
||||
<string name="tangempay_onboarding_banner_title">Tangem Visa Card</string>
|
||||
<string name="tangempay_onboarding_get_card_button_text">Karte erhalten</string>
|
||||
<string name="tangempay_onboarding_pay_description">Füge es Deiner Wallet hinzu und bezahle überall mit Deinem Smartphone.</string>
|
||||
<string name="tangempay_onboarding_pay_title">Apple Pay & Google Pay</string>
|
||||
<string name="tangempay_onboarding_purchases_description">Verwende Dein USDC-Guthaben, um alltägliche Einkäufe problemlos zu bezahlen.</string>
|
||||
<string name="tangempay_onboarding_purchases_title">Einkäufe im Alltag</string>
|
||||
<string name="tangempay_onboarding_security_description">Deine Kartendaten sind geschützt – volle Kontrolle in der App.</string>
|
||||
<string name="tangempay_onboarding_security_title">Integrierte Sicherheit</string>
|
||||
<string name="tangempay_onboarding_title">Hol Dir Deine kostenlose Crypto Card \n in wenigen Minuten</string>
|
||||
<string name="tangempay_onboarding_pay_description">Mit digitaler Karte, die mit Apple Pay und Google Pay funktioniert</string>
|
||||
<string name="tangempay_onboarding_pay_title">Geben Sie Ihre Vermögenswerte überall aus</string>
|
||||
<string name="tangempay_onboarding_purchases_description">Es fallen keine zusätzlichen Gebühren für Käufe an</string>
|
||||
<string name="tangempay_onboarding_purchases_title">Zahlen Sie genau das, was Sie sehen</string>
|
||||
<string name="tangempay_onboarding_security_description">Ein separates Zahlungskonto wird erstellt, ohne Ihre Adressen und Vermögenswerte offenzulegen</string>
|
||||
<string name="tangempay_onboarding_security_title">Unerreichte Privatsphäre</string>
|
||||
<string name="tangempay_onboarding_title">Erhalten Sie Ihre kostenlose Tangem Pay Card in wenigen Minuten</string>
|
||||
<string name="tangempay_payment_account">Payment account</string>
|
||||
<string name="tangempay_payment_account_sync_needed">Synchronisierung des Zahlungskontos erforderlich</string>
|
||||
<string name="tangempay_service_unavailable_description">Wir beheben ein technisches Problem. Bitte versuchen Sie es später erneut.</string>
|
||||
<string name="tangempay_service_unavailable_title">Service vorübergehend nicht verfügbar</string>
|
||||
<string name="tangempay_service_unreachable_try_later">Der Dienst ist derzeit nicht erreichbar. Bitte versuchen Sie es später erneut.</string>
|
||||
<string name="tangempay_sync_needed">Synchronisation erforderlich</string>
|
||||
<string name="tangempay_tangem_visa_card">Tangem Visa Card</string>
|
||||
<string name="tangempay_temporarily_unavailable">Tangem Pay ist vorübergehend nicht verfügbar</string>
|
||||
<string name="tangempay_title">Tangem Pay</string>
|
||||
<string name="tangempay_use_tangem_device_to_restore_payment_account">Verwenden Sie Ihre Karte oder Ihren Ring, um den Zugriff auf Ihr Zahlungskonto wiederherzustellen</string>
|
||||
<string name="tangempay_your_pin_code">Ihr PIN-Code</string>
|
||||
<string name="this_is_my_wallet_title">Das ist meine Wallet</string>
|
||||
<string name="toast_balances_hidden">Guthaben versteckt</string>
|
||||
<string name="toast_balances_shown">Angezeigte Salden</string>
|
||||
|
|
@ -1470,6 +1534,7 @@
|
|||
<string name="transaction_history_multiple_addresses">Mehrere Adressen</string>
|
||||
<string name="transaction_history_not_supported_description">Die Transaktionshistorie wird für diese Blockchain derzeit nicht verfügbar. Aber keine Sorge, wir arbeiten daran! In der Zwischenzeit kannst du es im Explorer überprüfen.</string>
|
||||
<string name="transaction_history_operation">Operation</string>
|
||||
<string name="transaction_history_transaction_for_address">für: %s</string>
|
||||
<string name="transaction_history_transaction_from_address">von: %s</string>
|
||||
<string name="transaction_history_transaction_to_address">zu: %s</string>
|
||||
<string name="transaction_history_transaction_validator">Validierer: %s</string>
|
||||
|
|
@ -1921,7 +1986,9 @@
|
|||
<string name="yield_module_fee_policy_sheet_title">Gebührenpolitik</string>
|
||||
<string name="yield_module_fee_policy_tangem_service_fee_title">Tangem erhebt außerdem eine Servicegebühr von 15% auf den erzielten Ertrag.</string>
|
||||
<string name="yield_module_high_fee_error">Deine Gelder werden automatisch an Aave überwiesen, sobald die Netzwerkgebühren niedriger sind oder Dein Guthaben den erforderlichen Mindestbetrag erreicht.</string>
|
||||
<string name="yield_module_high_network_fees_notification_title">Hohe Netzwerkgebühren</string>
|
||||
<string name="yield_module_historical_returns">Historische Renditen</string>
|
||||
<string name="yield_module_main_screen_promo_banner_message">Aktiviere %1$s%% Jahreszins auf Dein Guthaben</string>
|
||||
<string name="yield_module_main_view_approve_notification_description">Die Genehmigung für Deine Token im Yield-Modus wurde widerrufen. Öffne den Token, um die Berechtigung erneut zu erteilen.</string>
|
||||
<string name="yield_module_main_view_approve_notification_title">Token-Genehmigung erforderlich</string>
|
||||
<string name="yield_module_network_fee_unreachable_notification_description">Prüfe Deine Netzwerkverbindung</string>
|
||||
|
|
@ -1936,7 +2003,9 @@
|
|||
<string name="yield_module_promo_screen_self_custodial_title">Dezentral und selbstverwahrend</string>
|
||||
<string name="yield_module_promo_screen_terms_disclaimer">Durch die Nutzung dieses Dienstes erklärst Du Dich mit provider\n%1$s und %2$s einverstanden</string>
|
||||
<string name="yield_module_promo_screen_title">Mit Aave verbinden</string>
|
||||
<string name="yield_module_promo_screen_title_v2">Aktiviere %1$s%% APY\nauf Deinem Kontostand</string>
|
||||
<string name="yield_module_promo_screen_variable_rate_info">Aave %1$s%% • Variabler Zinssatz</string>
|
||||
<string name="yield_module_promo_screen_variable_rate_info_v2">Variabler Zinssatz</string>
|
||||
<string name="yield_module_provider">Aave</string>
|
||||
<string name="yield_module_rate_info_sheet_chart_average">Durchschnitt %s</string>
|
||||
<string name="yield_module_rate_info_sheet_chart_title">Renditen des letzten Jahres</string>
|
||||
|
|
@ -1967,8 +2036,11 @@
|
|||
<string name="yield_module_transaction_enter_subtitle">%1$s geliefert an Aave</string>
|
||||
<string name="yield_module_transaction_exit">Ertragsmodus deaktiviert</string>
|
||||
<string name="yield_module_transaction_exit_subtitle">%1$s aus Aave zurücküberwiesen</string>
|
||||
<string name="yield_module_transaction_initialize">Yield-Modus initialisieren</string>
|
||||
<string name="yield_module_transaction_reactivate">Yield-Modus reaktivieren</string>
|
||||
<string name="yield_module_transaction_topup">Lieferung an Aave</string>
|
||||
<string name="yield_module_transaction_topup_subtitle">%1$s geliefert an Aave</string>
|
||||
<string name="yield_module_transaction_withdraw">Abheben von Aave</string>
|
||||
<string name="yield_module_transfer_mode_automatic">Automatisch</string>
|
||||
<string name="yield_module_unable_to_cover_fee_description">Einzahlung von %1$s %2$s zur Deckung der Netzwerkgebühr für Transaktionen</string>
|
||||
<string name="yield_module_unable_to_cover_fee_title">Die Gebühr %s kann nicht gedeckt werden</string>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,21 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<resources>
|
||||
<string name="access_code_alert_skip_description">Sin un código de acceso, su billetera no es segura.</string>
|
||||
<string name="access_code_alert_skip_ok">Saltar de todos modos</string>
|
||||
<string name="access_code_alert_skip_title">Código de acceso no establecido</string>
|
||||
<string name="access_code_alert_validation_cancel">Cambiar código</string>
|
||||
<string name="access_code_alert_validation_description">Su código de acceso se utilizará para desbloquear su billetera y proteger el acceso a sus activos.</string>
|
||||
<string name="access_code_alert_validation_ok">Usar de todos modos</string>
|
||||
<string name="access_code_alert_validation_title">Este código de acceso se puede adivinar fácilmente.</string>
|
||||
<string name="access_code_check_title">Introduzca el código de acceso</string>
|
||||
<string name="access_code_check_warining_delete">Código de acceso incorrecto. Su billetera móvil se bloqueará tras %s intentos incorrectos más.</string>
|
||||
<string name="access_code_check_warining_lock">Código de acceso incorrecto. La aplicación se bloqueará tras %s intentos incorrectos más.</string>
|
||||
<string name="access_code_check_warining_wait">Código de acceso incorrecto.\nPor favor, espere %s segundos e inténtelo de nuevo.</string>
|
||||
<string name="access_code_confirm_description">Confirme su código de acceso para continuar</string>
|
||||
<string name="access_code_confirm_title">Vuelva a introducir el código de acceso</string>
|
||||
<string name="access_code_create_description">Establezca un código de acceso de %sdígitos para desbloquear su billetera.</string>
|
||||
<string name="access_code_create_title">Crear código de acceso</string>
|
||||
<string name="access_code_navtitle">Código de acceso</string>
|
||||
<string name="account_details_archive">Archivar cuenta</string>
|
||||
<string name="account_details_archive_action">Archivar</string>
|
||||
<string name="account_details_archive_description">Estás archivando esta cuenta, pero siempre puede recuperarla.</string>
|
||||
|
|
@ -38,16 +54,19 @@
|
|||
<string name="alert_manage_tokens_unsupported_message">Esta tarjeta no admite tokens en la red %1$s debido a una limitación del firmware.</string>
|
||||
<string name="alert_troubleshooting_scan_card_title">¿Tiene dificultades para escanear su tarjeta/anillo?</string>
|
||||
<string name="alert_unsupported_card">Esta tarjeta no está diseñada para funcionar con Tangem</string>
|
||||
<string name="app_settings_access_code_warning">Establezca primero un código de acceso para activar la biometría</string>
|
||||
<string name="app_settings_biometrics_footer">Utilice %1$s para desbloquear de forma rápida y segura su billetera y autorizar todas las acciones importantes, como la firma de transacciones. Al ser una billetera de hardware, seguirá necesitando una tarjeta para firmar.</string>
|
||||
<string name="app_settings_default_fee">Tarifa por defecto</string>
|
||||
<string name="app_settings_default_fee_footer">Habilite las Tarifas predeterminadas para establecer automáticamente las tarifas de transacción y omitir la página de Tarifas al enviar fondos. Siempre puede volver a esta página si es necesario.</string>
|
||||
<string name="app_settings_enable_biometrics_description">Vaya a ajustes para habilitar la autenticación biométrica en la Tangem App</string>
|
||||
<string name="app_settings_enable_biometrics_title">Habilitar autenticación biométrica</string>
|
||||
<string name="app_settings_off_biometrics_alert_message">Para deshabilitar %1$s deberá ingresar su código de acceso para desbloquear la aplicación e interactuar con su billetera.</string>
|
||||
<string name="app_settings_off_require_access_code_alert_message">Más tarde se le solicitará el código de acceso a su billetera para que podamos almacenarlo de forma segura para usarlo posteriormente</string>
|
||||
<string name="app_settings_off_saved_access_code_alert_message">Esto eliminará todos los códigos de acceso guardados de la billetera. Cualquier operación posterior con la billetera requerirá introducir el código de acceso.</string>
|
||||
<string name="app_settings_off_saved_wallet_alert_message">Eliminar la tarjeta guardada borra todos las billeteras guardadas y sus códigos de acceso de la app.</string>
|
||||
<string name="app_settings_on_require_access_code_alert_message">Esto borrará todos los códigos de acceso a la billetera guardados. Cualquier otra interacción con la billetera requerirá el envío del código de acceso.</string>
|
||||
<string name="app_settings_require_access_code">Requerir código de acceso</string>
|
||||
<string name="app_settings_require_access_code_footer">Esta opción desactiva la autenticación biométrica para acciones importantes. Se le pedirá que introduzca su código de acceso cada vez que, por ejemplo, deba firmar una transacción.</string>
|
||||
<string name="app_settings_require_access_code_footer">Esta opción desactiva el uso de datos biométricos para operaciones críticas. Tendrá que introducir su código de acceso cada vez que firme una transacción.</string>
|
||||
<string name="app_settings_saved_access_codes">Guardar código de acceso</string>
|
||||
<string name="app_settings_saved_access_codes_footer">Se solicitará la autenticación biométrica en lugar del código de acceso para las interacciones con su tarjeta o anillo.</string>
|
||||
<string name="app_settings_saved_wallet">Mantener la billetera en la app</string>
|
||||
|
|
@ -57,6 +76,9 @@
|
|||
<string name="app_settings_theme_mode_system">Predeterminado del sistema</string>
|
||||
<string name="app_settings_theme_selector_title">Tema</string>
|
||||
<string name="app_settings_title">Ajustes de la app</string>
|
||||
<string name="auth_info_add_wallet_title">Agregar billetera</string>
|
||||
<string name="auth_info_subtitle">Seleccione una billetera para iniciar sesión</string>
|
||||
<string name="auth_info_title">¡Bienvenido de nuevo!</string>
|
||||
<string name="backup_complete_description">Realizó una copia de seguridad de su billetera correctamente.</string>
|
||||
<string name="backup_complete_title">Copia de seguridad completada</string>
|
||||
<string name="backup_info_description">Su frase secreta de recuperación es un conjunto fijo de %s palabras aleatorias que se utilizan para acceder a su billetera y recuperarla.</string>
|
||||
|
|
@ -74,10 +96,17 @@
|
|||
<string name="balance_hidden_title">Los saldos están ocultos</string>
|
||||
<string name="beta_mode_warning_message">Según los desarrolladores de la blockchain, los tokens de Kaspa se encuentran actualmente en fase beta. ¡Estén atentos a las actualizaciones!</string>
|
||||
<string name="beta_mode_warning_title">Modo Beta</string>
|
||||
<string name="biometric_disabled_warning_description">La biometría está desactivada en su dispositivo, por lo que no puede utilizarla para desbloquear sus billeteras. Active la biometría en los ajustes de su dispositivo para volver a utilizar este método.</string>
|
||||
<string name="biometric_disabled_warning_title">Autenticación biométrica deshabilitada</string>
|
||||
<string name="biometric_lockout_permanent_warning_description">Por favor, escanee la tarjeta/anillo</string>
|
||||
<string name="biometric_lockout_permanent_warning_description_2">Ha alcanzado el límite de intentos biométricos. Desbloquee su billetera con un toque en su dispositivo o introduzca su código de acceso.</string>
|
||||
<string name="biometric_lockout_permanent_warning_title">Autenticación biométrica bloqueada</string>
|
||||
<string name="biometric_lockout_warning_description">Por favor, inténtelo de nuevo en 30 segundos o escanee la tarjeta/anillo</string>
|
||||
<string name="biometric_lockout_warning_description_2">El inicio de sesión biométrico está bloqueado temporalmente. Inténtalo de nuevo en 30 segundos o desbloquee su billetera con un toque del dispositivo o un código de acceso.</string>
|
||||
<string name="biometric_lockout_warning_title">Demasiados intentos</string>
|
||||
<string name="biometric_unavailable_warning">Ha desactivado la autenticación biométrica en su teléfono y no podrá guardar billeteras en la aplicación. Para guardar billeteras, active la función de autenticación biométrica en los ajustes de su teléfono.</string>
|
||||
<string name="biometric_updated_warning_description">Se han actualizado los datos biométricos de su dispositivo. Seleccione su billetera e introduzca su código de acceso para habilitar nuevamente el inicio de sesión biométrico.</string>
|
||||
<string name="biometric_updated_warning_title">Se requiere atención</string>
|
||||
<string name="bitcoin_promo_activation_error">Se produjo un error al procesar tu código promocional. Inténtalo de nuevo más tarde.</string>
|
||||
<string name="bitcoin_promo_activation_error_title">Error de activación</string>
|
||||
<string name="bitcoin_promo_activation_success">Tu código promocional se activó correctamente. Una recompensa se acreditará en tu cuenta dentro de 14 días.</string>
|
||||
|
|
@ -98,6 +127,13 @@
|
|||
<item quantity="one">%s token</item>
|
||||
<item quantity="other">%s tokens</item>
|
||||
</plurals>
|
||||
<string name="card_reset_alert_continue_message">Por favor restablezca el siguiente dispositivo para continuar.</string>
|
||||
<string name="card_reset_alert_continue_title">Restablecer billetera</string>
|
||||
<string name="card_reset_alert_finish_message">Se han restablecido todos sus dispositivos Tangem. Ya puede seguir actualizando su billetera.</string>
|
||||
<string name="card_reset_alert_finish_ok_button">Actualizar de nuevo</string>
|
||||
<string name="card_reset_alert_finish_title">Restablecimiento completo</string>
|
||||
<string name="card_reset_alert_incomplete_message">Recomendamos completar el proceso de restablecimiento para todos los dispositivos Tangem en esta billetera.</string>
|
||||
<string name="card_reset_alert_incomplete_title">No ha restablecido todos sus dispositivos Tangem</string>
|
||||
<string name="card_settings_access_code_recovery_disabled_description">Desactive esta opción si no quiere que esta tarjeta se use para reiniciar códigos de acceso en otras tarjetas de esta billetera. Tenga en cuenta que esto también evitará que reinicie el código de acceso en esta tarjeta.</string>
|
||||
<string name="card_settings_access_code_recovery_enabled_description">Permite usar esta tarjeta para reiniciar el código de acceso en otras tarjetas de esta billetera</string>
|
||||
<string name="card_settings_access_code_recovery_title">Recuperación de código de acceso</string>
|
||||
|
|
@ -123,19 +159,25 @@
|
|||
<string name="cardano_max_amount_has_token_title">ADA insuficiente</string>
|
||||
<string name="common_accept">Aceptar</string>
|
||||
<string name="common_access_denied">Acceso denegado</string>
|
||||
<string name="common_account">Cuenta</string>
|
||||
<string name="common_accounts">Cuentas</string>
|
||||
<string name="common_activate">Activar</string>
|
||||
<string name="common_add">Agregar</string>
|
||||
<string name="common_add_to_portfolio">Añadir al portafolio</string>
|
||||
<string name="common_add_token">Agregar token</string>
|
||||
<string name="common_added">Agregado</string>
|
||||
<string name="common_address">Dirección</string>
|
||||
<string name="common_all">Todos</string>
|
||||
<string name="common_allow">Autorizar</string>
|
||||
<string name="common_amount">Cantidad</string>
|
||||
<string name="common_analytics">Analítica</string>
|
||||
<string name="common_and">y</string>
|
||||
<string name="common_apply">Aplicar</string>
|
||||
<string name="common_approval">Aprobación</string>
|
||||
<string name="common_approve">Aprobar</string>
|
||||
<string name="common_attention">Atención</string>
|
||||
<string name="common_available_networks">Redes disponibles</string>
|
||||
<string name="common_backup">Copia de seguridad</string>
|
||||
<string name="common_balance">Saldo: %s</string>
|
||||
<string name="common_balance_title">Saldo</string>
|
||||
<string name="common_biometric_authentication">autenticación biométrica</string>
|
||||
|
|
@ -146,6 +188,7 @@
|
|||
<string name="common_camera_denied_alert_message">No ha otorgado acceso a su cámara, cambie su configuración de privacidad</string>
|
||||
<string name="common_cancel">Cancelar</string>
|
||||
<string name="common_change">Cambie</string>
|
||||
<string name="common_choose_account">Elegir cuenta</string>
|
||||
<string name="common_choose_action">Elige una acción</string>
|
||||
<string name="common_choose_network">Elija red</string>
|
||||
<string name="common_choose_token">Elija token</string>
|
||||
|
|
@ -156,6 +199,7 @@
|
|||
<string name="common_coming_soon">Próximamente</string>
|
||||
<string name="common_confirm">Confirme</string>
|
||||
<string name="common_connecting">Conectando</string>
|
||||
<string name="common_contact_support">Contactar con el equipo de soporte</string>
|
||||
<string name="common_contact_tangem_support">Contacte con el soporte de Tangem</string>
|
||||
<string name="common_contact_visa_support">Contacte con el soporte de Visa</string>
|
||||
<string name="common_continue">Continuar</string>
|
||||
|
|
@ -194,9 +238,13 @@
|
|||
<string name="common_fee_selector_option_slow">Lento</string>
|
||||
<string name="common_fee_selector_title">Velocidad y tarifa</string>
|
||||
<string name="common_finish">Finalizar</string>
|
||||
<string name="common_forget">Olvidar</string>
|
||||
<string name="common_free">Gratis</string>
|
||||
<string name="common_from">De</string>
|
||||
<string name="common_from_wallet_name">De %s</string>
|
||||
<string name="common_generate_addresses">Sincronizar direcciones</string>
|
||||
<string name="common_get_started">Comenzar</string>
|
||||
<string name="common_get_token">Obtener token</string>
|
||||
<string name="common_go_to_provider">Ir al proveedor</string>
|
||||
<string name="common_go_to_token">Ir al token</string>
|
||||
<string name="common_got_it">Entendido</string>
|
||||
|
|
@ -207,11 +255,19 @@
|
|||
<string name="common_later">Más tarde</string>
|
||||
<string name="common_learn_more">Más información</string>
|
||||
<string name="common_left">%1$s quedan</string>
|
||||
<string name="common_legacy_bitcoin_address">Legacy Bitcoin</string>
|
||||
<string name="common_locked">Bloqueado</string>
|
||||
<string name="common_locked_wallets">Billeteras bloqueadas</string>
|
||||
<string name="common_main_network">Red principal</string>
|
||||
<string name="common_month">mes</string>
|
||||
<string name="common_network_fee_title">Tarifa de la red</string>
|
||||
<string name="common_network_fee_warning_content">La cantidad enviada se reducirá en %1$s (%2$s) para cubrir el nivel de tarifa seleccionado</string>
|
||||
<plurals name="common_networks_count">
|
||||
<item quantity="one">%d red</item>
|
||||
<item quantity="other">%d redes</item>
|
||||
</plurals>
|
||||
<string name="common_new_address">Nueva dirección</string>
|
||||
<string name="common_news">Noticias</string>
|
||||
<string name="common_next">Siguiente</string>
|
||||
<string name="common_nft">NFT</string>
|
||||
<string name="common_no">No</string>
|
||||
|
|
@ -230,10 +286,12 @@
|
|||
<string name="common_range_with_space">%1$s — %2$s</string>
|
||||
<string name="common_read_more">Leer más</string>
|
||||
<string name="common_receive">Recibir</string>
|
||||
<string name="common_recommended">Recomendado</string>
|
||||
<string name="common_reject">Rechazar</string>
|
||||
<string name="common_reload">Recargar</string>
|
||||
<string name="common_rename">Renombrar</string>
|
||||
<string name="common_required">Requerido</string>
|
||||
<string name="common_reset">Resetear</string>
|
||||
<string name="common_save">Guarde</string>
|
||||
<string name="common_save_changes">Guardar cambios</string>
|
||||
<string name="common_search">Buscar</string>
|
||||
|
|
@ -252,6 +310,8 @@
|
|||
<string name="common_show_more">Mostrar más</string>
|
||||
<string name="common_sign">Firme</string>
|
||||
<string name="common_sign_and_send">Firme y envíe</string>
|
||||
<string name="common_skip">Saltar</string>
|
||||
<string name="common_something_went_wrong">Algo salió mal</string>
|
||||
<string name="common_stake">Stake</string>
|
||||
<string name="common_staking">Staking</string>
|
||||
<string name="common_start">Empezar</string>
|
||||
|
|
@ -260,9 +320,12 @@
|
|||
<string name="common_support">Soporte</string>
|
||||
<string name="common_supported_networks">Redes soportadas</string>
|
||||
<string name="common_swap">Intercambiar</string>
|
||||
<string name="common_tangem">Tangem</string>
|
||||
<string name="common_tangem_wallet">Tangem Wallet</string>
|
||||
<string name="common_terms_and_conditions">términos y condiciones</string>
|
||||
<string name="common_terms_of_use">Condiciones de uso</string>
|
||||
<string name="common_to">A</string>
|
||||
<string name="common_to_wallet_name">A %s</string>
|
||||
<string name="common_today">Hoy</string>
|
||||
<plurals name="common_tokens_count">
|
||||
<item quantity="one">%d token</item>
|
||||
|
|
@ -272,6 +335,7 @@
|
|||
<string name="common_transaction_status">Estado de la transacción</string>
|
||||
<string name="common_transactions">Transacciones</string>
|
||||
<string name="common_transfer">Transferencia</string>
|
||||
<string name="common_unable_to_load">No se pueden cargar los datos…</string>
|
||||
<string name="common_understand">Entiendo</string>
|
||||
<string name="common_unknown_error">Hubo un error. Por favor inténtelo de nuevo.</string>
|
||||
<string name="common_unreachable">Inaccesible</string>
|
||||
|
|
@ -323,7 +387,6 @@
|
|||
<string name="details_row_description_flip_to_hide">Gire la pantalla de su dispositivo hacia abajo para ocultar y mostrar rápidamente los saldos</string>
|
||||
<string name="details_row_subtitle_signed_hashes_format">%s hashes</string>
|
||||
<string name="details_row_title_cid">ID del dispositivo</string>
|
||||
<string name="details_row_title_contact_to_support">Contactar con el equipo de soporte</string>
|
||||
<string name="details_row_title_contact_to_support_chat">Abrir chat de soporte</string>
|
||||
<string name="details_row_title_create_backup">Vincular más tarjetas</string>
|
||||
<string name="details_row_title_currency">Moneda de la aplicación</string>
|
||||
|
|
@ -447,6 +510,7 @@
|
|||
<string name="home_button_create_new_wallet">Crear Nueva Billetera</string>
|
||||
<string name="home_button_order">Pedir Tangem</string>
|
||||
<string name="home_button_scan">Escanee</string>
|
||||
<string name="hot_access_code_set_biometric_ask">¿Quiere permitir que \"Tangem\" utilice la autenticación biométrica? Para confirmar su identidad y abrir la aplicación</string>
|
||||
<string name="hot_crypto_add_token_subtitle">a %s</string>
|
||||
<string name="hot_crypto_token_network">En la red %s</string>
|
||||
<string name="hw_access_code_create_alert_title">¿Está seguro de que desea salir del proceso de creación de código de acceso?</string>
|
||||
|
|
@ -504,11 +568,13 @@
|
|||
<string name="markets_apy_placeholder">APY %s</string>
|
||||
<string name="markets_common_my_portfolio">Mi portafolio</string>
|
||||
<string name="markets_common_title">Mercado</string>
|
||||
<string name="markets_earn_common_title">Gane con Tangem</string>
|
||||
<string name="markets_generate_addresses_notification">Para generar direcciones para las redes seleccionadas, debe escanear su tarjeta Tangem</string>
|
||||
<string name="markets_hint">Para agregar tokens, abra esta página o pulse sobre la barra de búsqueda</string>
|
||||
<string name="markets_insights_info_description_message">Los datos de este apartado proceden de las siguientes redes: %s</string>
|
||||
<string name="markets_loading_error_title">No se pueden cargar los datos…</string>
|
||||
<string name="markets_loading_no_data_title">Sin datos</string>
|
||||
<string name="markets_pulse_common_title">Análisis del Mercado</string>
|
||||
<string name="markets_quick_actions">Acciones rápidas</string>
|
||||
<string name="markets_search_header_title">Busque en el mercado</string>
|
||||
<string name="markets_search_result_title">Resultado</string>
|
||||
|
|
@ -598,6 +664,10 @@
|
|||
<string name="markets_token_details_volume">Volumen</string>
|
||||
<string name="markets_tooltip_message">Tire hacia arriba o toque la barra de búsqueda para agregar tokens directamente desde el mercado</string>
|
||||
<string name="markets_tooltip_title">Agregar tokens</string>
|
||||
<string name="markets_yield_supply_banner_description">Potencie sus activos mientras los suministra con acceso inmediato. %s</string>
|
||||
<string name="markets_yield_supply_banner_title">Activar Modo Rendimiento</string>
|
||||
<string name="mobile_wallet_requires_min_os_warning_body">Debes actualizar a %1$s para crear una mobile wallet</string>
|
||||
<string name="mobile_wallet_requires_min_os_warning_title">Mobile Wallet requiere %1$s o posterior</string>
|
||||
<string name="nfc_error_unavailable">NFC no está disponible en su dispositivo</string>
|
||||
<string name="nft_about_title">Acerca de NFT</string>
|
||||
<string name="nft_asset">Activo NFT</string>
|
||||
|
|
@ -654,6 +724,9 @@
|
|||
<string name="no_trustline_xlm_asset">La cuenta de destino no tiene una Trustline (línea de confianza) para el activo que se envía.</string>
|
||||
<string name="notification_black_friday_text">Obtén $10 en BTC con cada billetera \n ¡Date prisa!</string>
|
||||
<string name="notification_black_friday_title">Black Friday: hasta 30% DESCUENTO</string>
|
||||
<string name="notification_one_plus_one_button">Vamos</string>
|
||||
<string name="notification_one_plus_one_text">Crea el par perfecto de packs de Tangem. Por tiempo limitado.</string>
|
||||
<string name="notification_one_plus_one_title">1+1: Compra una billetera y obtén un 50% dto. en la segunda</string>
|
||||
<string name="notification_referral_promo_button">Únase ahora</string>
|
||||
<string name="notification_referral_promo_text">Comparta su código y gane 5 USDT por venta. Su amigo obtiene un 10% de descuento.</string>
|
||||
<string name="notification_referral_promo_title">¡Obtenga RECOMPENSAS por cada amigo!</string>
|
||||
|
|
@ -1152,6 +1225,111 @@
|
|||
<string name="swapping_to_title">Usted recibe</string>
|
||||
<string name="swapping_token_list_title">Elige token</string>
|
||||
<string name="swapping_token_not_available">no disponible</string>
|
||||
<string name="tangem_pay_beta_notification_subtitle">Nos encantaría recibir tus comentarios</string>
|
||||
<string name="tangem_pay_beta_notification_title">Tangem Pay ya está en beta</string>
|
||||
<string name="tangem_pay_card_frozen">Tarjeta congelada</string>
|
||||
<string name="tangem_pay_card_payment">Pago con tarjeta</string>
|
||||
<string name="tangem_pay_deposit">Depósito</string>
|
||||
<string name="tangem_pay_dispute">Disputar</string>
|
||||
<string name="tangem_pay_explore_transaction">Explorar transacción</string>
|
||||
<string name="tangem_pay_fee_subtitle">Comisiones</string>
|
||||
<string name="tangem_pay_fee_title">Comisión</string>
|
||||
<string name="tangem_pay_freeze_card_alert_body">Mantén tu dinero seguro. Puedes desbloquear en cualquier momento.</string>
|
||||
<string name="tangem_pay_freeze_card_alert_title">¿Congelar tu tarjeta?</string>
|
||||
<string name="tangem_pay_freeze_card_failed">No se pudo congelar la tarjeta. Inténtalo de nuevo más tarde.</string>
|
||||
<string name="tangem_pay_freeze_card_freeze">Mantén tu dinero seguro. Puedes desbloquear en cualquier momento.</string>
|
||||
<string name="tangem_pay_freeze_card_success">Tu tarjeta está congelada.</string>
|
||||
<string name="tangem_pay_get_help">Obtener ayuda</string>
|
||||
<string name="tangem_pay_other">Otro</string>
|
||||
<string name="tangem_pay_status_completed">Completado</string>
|
||||
<string name="tangem_pay_status_declined">Rechazado</string>
|
||||
<string name="tangem_pay_status_pending">Pendiente</string>
|
||||
<string name="tangem_pay_terms_fees_limits">Términos, tarifas y límites</string>
|
||||
<string name="tangem_pay_terms_limits">Términos y límites</string>
|
||||
<string name="tangem_pay_transaction_declined_notification_text">El banco rechazó esta solicitud de transacción.</string>
|
||||
<string name="tangem_pay_transaction_fee_notification_text">Esta tarifa cubre el costo de procesar tu transferencia.</string>
|
||||
<string name="tangem_pay_unfreeze_card_alert_body">Sigue usando tu dinero. Puedes congelarlo en cualquier momento.</string>
|
||||
<string name="tangem_pay_unfreeze_card_alert_title">¿Descongelar tu tarjeta?</string>
|
||||
<string name="tangem_pay_unfreeze_card_failed">No se pudo descongelar la tarjeta. Inténtalo de nuevo más tarde.</string>
|
||||
<string name="tangem_pay_unfreeze_card_success">Tu tarjeta está descongelada.</string>
|
||||
<string name="tangem_pay_withdrawal">Retirada</string>
|
||||
<string name="tangempay_card_details_add_funds">Agregar fondos</string>
|
||||
<string name="tangempay_card_details_add_funds_subtitle">Opciones de recarga</string>
|
||||
<string name="tangempay_card_details_card_number">Número de tarjeta</string>
|
||||
<string name="tangempay_card_details_change_pin">Modificar PIN</string>
|
||||
<string name="tangempay_card_details_change_pin_success_description">La tarjeta está completamente lista para pagos.</string>
|
||||
<string name="tangempay_card_details_change_pin_success_title">Código PIN creado</string>
|
||||
<string name="tangempay_card_details_cvc">CVC</string>
|
||||
<string name="tangempay_card_details_error_text">Error al cargar datos. Inténtalo de nuevo más tarde.</string>
|
||||
<string name="tangempay_card_details_expiry">Caducidad</string>
|
||||
<string name="tangempay_card_details_freeze_card">Congelar tarjeta</string>
|
||||
<string name="tangempay_card_details_hide_details">Ocultar detalles</string>
|
||||
<string name="tangempay_card_details_hide_text">Ocultar</string>
|
||||
<string name="tangempay_card_details_open_wallet_button">Abrir Google Wallet</string>
|
||||
<string name="tangempay_card_details_open_wallet_notification_subtitle">Configura Tangem Pay en unos pocos toques y empieza a pagar con Google Pay.</string>
|
||||
<string name="tangempay_card_details_open_wallet_notification_subtitle_apple">Configura Tangem Pay en unos pocos toques y empieza a pagar con Apple Pay</string>
|
||||
<string name="tangempay_card_details_open_wallet_notification_title">Añade tu tarjeta a Google Pay</string>
|
||||
<string name="tangempay_card_details_open_wallet_notification_title_apple">Añade tu tarjeta a Apple Pay</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_1">Abrir Google Wallet</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_1_5_apple">Toque el botón \"+\" en la parte superior derecha</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_1_apple">Abrir Apple Wallet</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_2">Toca \"Añadir tarjeta\"</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_2_apple">Toque “Tarjeta de débito o crédito”</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_3">Ingresa los detalles de la tarjeta manualmente</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_4">Verifica la tarjeta usando el OTP enviado a tu dispositivo.</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_5">¡Todo listo! Tu tarjeta está lista para usar.</string>
|
||||
<string name="tangempay_card_details_open_wallet_title">Añadir tarjeta a Google Pay</string>
|
||||
<string name="tangempay_card_details_open_wallet_title_apple">Añade tu tarjeta a Apple Pay</string>
|
||||
<string name="tangempay_card_details_receive_description">Comparte tu dirección o muestra el código QR</string>
|
||||
<string name="tangempay_card_details_receive_error_title">Recepción no disponible ahora</string>
|
||||
<string name="tangempay_card_details_reveal_text">Mostrar</string>
|
||||
<string name="tangempay_card_details_show_details">Mostrar detalles</string>
|
||||
<string name="tangempay_card_details_swap_description">Intercambia cualquier activo de tu portafolio por una tarjeta</string>
|
||||
<string name="tangempay_card_details_title">Detalles de la tarjeta</string>
|
||||
<string name="tangempay_card_details_unfreeze_card">Descongelar tarjeta</string>
|
||||
<string name="tangempay_card_details_withdraw">Retirar</string>
|
||||
<string name="tangempay_card_details_withdraw_error_title">Retiro no disponible ahora</string>
|
||||
<string name="tangempay_card_details_withdraw_in_progress_description">No puedes iniciar un intercambio o un nuevo retiro hasta que el actual finalice.</string>
|
||||
<string name="tangempay_card_details_withdraw_in_progress_title">Retiro en progreso</string>
|
||||
<string name="tangempay_change_pin_code">Cambiar código PIN</string>
|
||||
<string name="tangempay_come_back_if_forget_pin">Vuelve a la app si lo olvidas.</string>
|
||||
<string name="tangempay_failed_to_issue_card">Error al emitir la tarjeta</string>
|
||||
<string name="tangempay_failed_to_issue_card_retry_description">Ha ocurrido un error técnico, por favor inténtalo de nuevo haciendo clic en el botón de abajo</string>
|
||||
<string name="tangempay_failed_to_issue_card_support_description">Ha ocurrido un error técnico, por favor contacta con el soporte</string>
|
||||
<string name="tangempay_get_banner_description">Usa tus criptomonedas para compras en el mundo real. \nEs una tarjeta de pago única en su tipo.</string>
|
||||
<string name="tangempay_get_tangem_pay">Obtener Tangem Pay</string>
|
||||
<string name="tangempay_go_to_support">Ir a Soporte</string>
|
||||
<string name="tangempay_issue_card_notification_description">Suele tardar hasta 15 minutos</string>
|
||||
<string name="tangempay_issue_card_notification_title">Configurando tu tarjeta Tangem</string>
|
||||
<string name="tangempay_issuing_your_card">Emisión de su tarjeta</string>
|
||||
<string name="tangempay_issuing_your_card_description">Estamos preparando tu tarjeta. Esto puede llevar un poco de tiempo.</string>
|
||||
<string name="tangempay_kyc_card_ready_notification_title">Tangem Pay</string>
|
||||
<string name="tangempay_kyc_failed_description">No pudimos verificar tu perfil. Si tienes alguna pregunta, contacta con el soporte.</string>
|
||||
<string name="tangempay_kyc_failed_title">Lamentablemente, no pudimos verificar tu identidad</string>
|
||||
<string name="tangempay_kyc_in_progress">KYC en curso</string>
|
||||
<string name="tangempay_kyc_in_progress_notification_button">Ver estado</string>
|
||||
<string name="tangempay_kyc_in_progress_notification_title">KYC en progreso para Tangem Pay</string>
|
||||
<string name="tangempay_onboarding_banner_description">Usa tus criptomonedas para compras en el mundo real. \nEs una tarjeta de pago única en su tipo.</string>
|
||||
<string name="tangempay_onboarding_banner_title">Tangem Visa Card</string>
|
||||
<string name="tangempay_onboarding_get_card_button_text">Obtener tarjeta</string>
|
||||
<string name="tangempay_onboarding_pay_description">Con tarjeta digital que funciona con Apple Pay y Google Pay</string>
|
||||
<string name="tangempay_onboarding_pay_title">Gasta tus activos en cualquier lugar</string>
|
||||
<string name="tangempay_onboarding_purchases_description">No hay comisiones adicionales por compras</string>
|
||||
<string name="tangempay_onboarding_purchases_title">Paga exactamente lo que ves</string>
|
||||
<string name="tangempay_onboarding_security_description">Se creará una cuenta de pago separada sin divulgar tus direcciones y activos</string>
|
||||
<string name="tangempay_onboarding_security_title">Privacidad inigualable</string>
|
||||
<string name="tangempay_onboarding_title">Obtén tu tarjeta Tangem Pay gratuita en minutos</string>
|
||||
<string name="tangempay_payment_account">Payment account</string>
|
||||
<string name="tangempay_payment_account_sync_needed">Sincronización de cuenta de pago necesaria</string>
|
||||
<string name="tangempay_service_unavailable_description">Estamos solucionando un problema técnico. Por favor, inténtelo de nuevo más tarde.</string>
|
||||
<string name="tangempay_service_unavailable_title">Servicio temporalmente no disponible</string>
|
||||
<string name="tangempay_service_unreachable_try_later">El servicio no está disponible actualmente. Inténtalo de nuevo más tarde.</string>
|
||||
<string name="tangempay_sync_needed">Sincronización necesaria</string>
|
||||
<string name="tangempay_tangem_visa_card">Tangem Visa Card</string>
|
||||
<string name="tangempay_temporarily_unavailable">Tangem Pay temporalmente no disponible</string>
|
||||
<string name="tangempay_title">Tangem Pay</string>
|
||||
<string name="tangempay_use_tangem_device_to_restore_payment_account">Usa tu tarjeta o anillo para restaurar el acceso a tu cuenta de pago</string>
|
||||
<string name="tangempay_your_pin_code">Tu código PIN</string>
|
||||
<string name="this_is_my_wallet_title">Esta es mi billetera</string>
|
||||
<string name="toast_balances_hidden">Saldos ocultos</string>
|
||||
<string name="toast_balances_shown">Saldos mostrados</string>
|
||||
|
|
@ -1239,6 +1417,7 @@
|
|||
<string name="user_wallet_list_rename_popup_title">Renombrar la billetera</string>
|
||||
<string name="user_wallet_list_unlock_all">Desbloquear todo</string>
|
||||
<string name="user_wallet_list_unlock_all_with">Desbloquear todo con %s</string>
|
||||
<string name="wallet_add_common_title">Elija cómo agregar su billetera</string>
|
||||
<string name="wallet_balance_blockchain_unreachable_try_later">La blockchain está Inaccesible. Inténtelo más tarde</string>
|
||||
<string name="wallet_balance_missing_derivation">Escanee la tarjeta o el anillo</string>
|
||||
<string name="wallet_been_activated_message">Esta billetera ya ha sido activada anteriormente.\nSi no fue usted quien lo hizo, comuníquese con el servicio de asistencia.\nTangem nunca vende billeteras con un código de acceso pre generado.</string>
|
||||
|
|
@ -1274,10 +1453,21 @@
|
|||
<string name="wallet_connect_subtitle">Conectar a dApps</string>
|
||||
<string name="wallet_connect_title">WalletConnect</string>
|
||||
<string name="wallet_connect_toast_awaiting_session_proposal">La conexión puede tardar unos segundos.</string>
|
||||
<string name="wallet_create_common_title">Crear una billetera Tangem</string>
|
||||
<string name="wallet_import_buy_question">¿Quiere comprar Tangem Wallet?</string>
|
||||
<string name="wallet_import_buy_title">Comprar ahora</string>
|
||||
<string name="wallet_import_google_drive_description">Recuperar una billetera existente mediante copia de seguridad de Google Drive</string>
|
||||
<string name="wallet_import_google_drive_title">Importar desde Google Drive</string>
|
||||
<string name="wallet_import_navtitle">Agregar billetera existente</string>
|
||||
<string name="wallet_import_scan_description">Dispositivos físicos que almacenan de forma segura su clave privada fuera de línea.</string>
|
||||
<string name="wallet_import_scan_title">Escanee una billetera Tangem</string>
|
||||
<string name="wallet_import_seed_description">Importa una billetera existente con su frase de recuperación.</string>
|
||||
<string name="wallet_import_seed_navtitle">Importar billetera</string>
|
||||
<string name="wallet_import_seed_title">Introduzca la frase de recuperación</string>
|
||||
<string name="wallet_import_success_description">La copia de seguridad de su billetera se realizó con éxito.</string>
|
||||
<string name="wallet_import_success_navtitle">Importar billetera</string>
|
||||
<string name="wallet_import_success_title">Importación completada</string>
|
||||
<string name="wallet_import_title">Importar billetera</string>
|
||||
<string name="wallet_marketplace_block_title">%s Precio de mercado</string>
|
||||
<string name="wallet_marketprice_block_update_time">últimas 24h</string>
|
||||
<string name="wallet_network_group_title">%s red</string>
|
||||
|
|
@ -1286,8 +1476,11 @@
|
|||
<string name="wallet_promo_banner_button_title">Consíguelo ahora con un 10 % de descuento</string>
|
||||
<string name="wallet_promo_banner_description">Acceda a más de 13.000 criptomonedas. Compre, venda, intercambie y realice staking con un solo toque.\nVincule hasta tres tarjetas para hacer copias de seguridad.</string>
|
||||
<string name="wallet_promo_banner_title">Descubra Tangem Wallet</string>
|
||||
<string name="wallet_settings_access_code_description">Este código de acceso protege su billetera y se utiliza para iniciar sesión y firmar transacciones.</string>
|
||||
<string name="wallet_settings_access_code_title">Establecer/Cambiar código de acceso</string>
|
||||
<string name="wallet_settings_change_access_code_title">Cambiar código de acceso</string>
|
||||
<string name="wallet_settings_push_notifications_description">Manténgase informado sobre las transacciones entrantes de la billetera y las actualizaciones de Tangem.</string>
|
||||
<string name="wallet_settings_push_notifications_huawei_warning">Es posible que las notificaciones push no funcionen actualmente en dispositivos Huawei. Estamos trabajando activamente en una solución y la publicaremos en una próxima actualización. ¡Gracias por su comprensión!</string>
|
||||
<string name="wallet_settings_push_notifications_title">Notificaciones de transacciones</string>
|
||||
<string name="wallet_settings_set_access_code_title">Establecer código de acceso</string>
|
||||
<string name="wallet_settings_title">Ajustes de la wallet</string>
|
||||
|
|
@ -1477,6 +1670,20 @@
|
|||
<string name="wc_uri_already_used_title">URI ya utilizado</string>
|
||||
<string name="wc_wallet_connect">WalletConnect</string>
|
||||
<string name="wc_warning_transaction">Transacción sospechosa</string>
|
||||
<string name="welcome_create_wallet_already_have">¿Ya tiene Tangem Wallet?</string>
|
||||
<string name="welcome_create_wallet_feature_assets">Miles de activos</string>
|
||||
<string name="welcome_create_wallet_feature_class">La mejor billetera de hardware de su clase</string>
|
||||
<string name="welcome_create_wallet_feature_delivery">Entrega rápida</string>
|
||||
<string name="welcome_create_wallet_feature_one_tap">Empiece con un solo toque</string>
|
||||
<string name="welcome_create_wallet_feature_seamless">Fácil y seguro</string>
|
||||
<string name="welcome_create_wallet_feature_use">Fácil de usar</string>
|
||||
<string name="welcome_create_wallet_hardware_description">Cree una billetera de hardware con Tangem. Delgada como una tarjeta bancaria, segura como una bóveda.</string>
|
||||
<string name="welcome_create_wallet_mobile_description">Crear o importar una billetera de software</string>
|
||||
<string name="welcome_create_wallet_mobile_description_full">Cree o importe una billetera de software en su teléfono.</string>
|
||||
<string name="welcome_create_wallet_mobile_title">Empezar con Mobile Wallet</string>
|
||||
<string name="welcome_create_wallet_other_method">Otro método</string>
|
||||
<string name="welcome_create_wallet_use_hardware_description">Utilice la billetera de hardware Tangem</string>
|
||||
<string name="welcome_create_wallet_use_hardware_title">Obtenga más información y compre</string>
|
||||
<string name="welcome_interrupted_backup_alert_discard">Ignorar</string>
|
||||
<string name="welcome_interrupted_backup_alert_message">Tiene un backup interrumpido. ¿Quiere reanudarlo?</string>
|
||||
<string name="welcome_interrupted_backup_alert_resume">Sí, reanudar</string>
|
||||
|
|
@ -1491,14 +1698,14 @@
|
|||
<string name="xtz_withdrawal_message_ignore">No, enviar todo</string>
|
||||
<string name="xtz_withdrawal_message_reduce">Reducir en %s XTZ</string>
|
||||
<string name="xtz_withdrawal_message_warning">Para evitar pagar una comisión mayor la próxima vez que recargue su billetera, reduzca el importe en %s XTZ</string>
|
||||
<string name="yield_module_alert_description">Con el modo Rendimiento activo, todos los depósitos futuros a esta dirección irán a Aave. Puede seguir gestionando sus fondos libremente.</string>
|
||||
<string name="yield_module_alert_description">Con el Modo Rendimiento activo, todos los depósitos futuros a esta dirección irán a Aave. Puede seguir gestionando sus fondos libremente.</string>
|
||||
<string name="yield_module_alert_title">Su %s se suministra a Aave</string>
|
||||
<string name="yield_module_amount_not_transfered_to_aave_title">El suministro de %1$s %2$s a Aave está pendiente</string>
|
||||
<string name="yield_module_approve_needed_notification_cta">Aprobar</string>
|
||||
<string name="yield_module_approve_needed_notification_description">Se ha revocado la aprobación de su token. Concédalo de nuevo para reanudar el servicio.</string>
|
||||
<string name="yield_module_approve_needed_notification_title">Aprobación necesaria</string>
|
||||
<string name="yield_module_approve_sheet_fee_note">Se le descontará la comisión y se le volverán a prestar sus activos.</string>
|
||||
<string name="yield_module_approve_sheet_subtitle">Para seguir ganando, se requiere aprobación.</string>
|
||||
<string name="yield_module_approve_sheet_fee_note">Se le descontará la comisión y se volverán a suministrar sus activos.</string>
|
||||
<string name="yield_module_approve_sheet_subtitle">Para seguir generando rendimiento, se requiere aprobación.</string>
|
||||
<string name="yield_module_approve_sheet_title">Confirmar aprobación</string>
|
||||
<string name="yield_module_balance_info_sheet_subtitle">Sus fondos se suministran actualmente al protocolo Aave, pero puede gestionarlos en cualquier momento.</string>
|
||||
<string name="yield_module_balance_info_sheet_title">Su %s está depositado en Aave</string>
|
||||
|
|
@ -1527,8 +1734,11 @@
|
|||
<string name="yield_module_fee_policy_sheet_title">Política de tarifas</string>
|
||||
<string name="yield_module_fee_policy_tangem_service_fee_title">Tangem también cobra una comisión de servicio del 15% sobre el rendimiento obtenido.</string>
|
||||
<string name="yield_module_high_fee_error">Sus fondos se suministrarán automáticamente a Aave una vez que las comisiones de red sean más bajas o su saldo alcance el importe mínimo requerido.</string>
|
||||
<string name="yield_module_high_network_fees_notification_description">Las comisiones son más altas de lo habitual debido a la alta actividad del mercado. Puede continuar ahora o volver a consultar más tarde cuando las comisiones sean más bajas.</string>
|
||||
<string name="yield_module_high_network_fees_notification_title">Tarifas de red elevadas</string>
|
||||
<string name="yield_module_historical_returns">Rendimientos históricos</string>
|
||||
<string name="yield_module_main_view_approve_notification_description">Se ha revocado la autorización para su token en el modo Rendimiento. Abra el token para volver a conceder el permiso.</string>
|
||||
<string name="yield_module_main_screen_promo_banner_message">Consiga un %1$s%% APY sobre su saldo</string>
|
||||
<string name="yield_module_main_view_approve_notification_description">Se ha revocado la autorización para su token en el Modo Rendimiento. Abra el token para volver a conceder el permiso.</string>
|
||||
<string name="yield_module_main_view_approve_notification_title">Se necesita la aprobación de Token</string>
|
||||
<string name="yield_module_network_fee_unreachable_notification_description">Compruebe su conexión de red</string>
|
||||
<string name="yield_module_network_fee_unreachable_notification_title">Información de tarifas de red inaccesible</string>
|
||||
|
|
@ -1542,7 +1752,9 @@
|
|||
<string name="yield_module_promo_screen_self_custodial_title">Descentralizado y autocustodiado</string>
|
||||
<string name="yield_module_promo_screen_terms_disclaimer">Al utilizar este servicio, usted acepta que el proveedor\n%1$s y %2$s</string>
|
||||
<string name="yield_module_promo_screen_title">Conectar Aave</string>
|
||||
<string name="yield_module_promo_screen_title_v2">Consiga un %1$s%% APY\nen su saldo</string>
|
||||
<string name="yield_module_promo_screen_variable_rate_info">Aave %1$s%% - Tipo de interés variable</string>
|
||||
<string name="yield_module_promo_screen_variable_rate_info_v2">Tipo de interés variable</string>
|
||||
<string name="yield_module_provider">Aave</string>
|
||||
<string name="yield_module_rate_info_sheet_chart_average">Promedio %s</string>
|
||||
<string name="yield_module_rate_info_sheet_chart_title">Resultados del año pasado</string>
|
||||
|
|
@ -1558,7 +1770,7 @@
|
|||
<string name="yield_module_status_active">Activo</string>
|
||||
<string name="yield_module_status_paused">En pausa</string>
|
||||
<string name="yield_module_stop_earning">Desactivación del modo de rendimiento</string>
|
||||
<string name="yield_module_stop_earning_sheet_description">Al desactivar esto, retirará sus fondos de Aave a %s en su billetera y dejará de ganar recompensas.</string>
|
||||
<string name="yield_module_stop_earning_sheet_description">Al desactivar esto, retirará sus fondos de Aave a %s en su billetera y dejará de generar rendimientos.</string>
|
||||
<string name="yield_module_stop_earning_sheet_fee_note">Se cobra una comisión de red por la blockchain al salir del modo Yield.</string>
|
||||
<string name="yield_module_stop_earning_sheet_title">Desactivar el modo de rendimiento</string>
|
||||
<string name="yield_module_supply">Suministrar</string>
|
||||
|
|
@ -1569,16 +1781,20 @@
|
|||
<string name="yield_module_token_details_earn_notification_earning_on_your_balance_title">Modo de rendimiento</string>
|
||||
<string name="yield_module_token_details_earn_notification_processing">Procesando su depósito</string>
|
||||
<string name="yield_module_token_details_earn_notification_title">Modo Rendimiento</string>
|
||||
<string name="yield_module_transaction_deploy_contract">Implementación del contrato del Modo Rendimiento</string>
|
||||
<string name="yield_module_transaction_enter">Modo Rendimiento activado</string>
|
||||
<string name="yield_module_transaction_enter_subtitle">%1$s suministrado a Aave</string>
|
||||
<string name="yield_module_transaction_exit">Modo Rendimiento desactivado</string>
|
||||
<string name="yield_module_transaction_exit_subtitle">%1$s retirado de Aave</string>
|
||||
<string name="yield_module_transaction_initialize">Iniciar Modo Rendimiento</string>
|
||||
<string name="yield_module_transaction_reactivate">Reactivar Modo Rendimiento</string>
|
||||
<string name="yield_module_transaction_topup">Suministrar a Aave</string>
|
||||
<string name="yield_module_transaction_topup_subtitle">%1$s suministrado a Aave</string>
|
||||
<string name="yield_module_transaction_withdraw">Retirar de Aave</string>
|
||||
<string name="yield_module_transfer_mode_automatic">Automático</string>
|
||||
<string name="yield_module_unable_to_cover_fee_description">Deposite algo de %1$s %2$s para cubrir la tarifa de red para las transacciones</string>
|
||||
<string name="yield_module_unable_to_cover_fee_title">No se puede cubrir la tarifa %s</string>
|
||||
<string name="yield_module_unavailable_subtitle">El servicio de intereses no está disponible en este momento. Vuelva a intentarlo más tarde.</string>
|
||||
<string name="yield_module_unavailable_subtitle">El Modo de Rendimiento no está disponible en este momento. Vuelva a intentarlo más tarde.</string>
|
||||
<string name="yield_module_unavailable_title">Modo de rendimiento no disponible</string>
|
||||
<string name="yield_supply_chart_loading_error">No se puede cargar el gráfico...</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,21 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<resources>
|
||||
<string name="access_code_alert_skip_description">Sans code d\'accès, votre portefeuille n\'est pas sécurisé.</string>
|
||||
<string name="access_code_alert_skip_ok">Ignorer quand même</string>
|
||||
<string name="access_code_alert_skip_title">Code d\'accès non défini</string>
|
||||
<string name="access_code_alert_validation_cancel">Modifier le code</string>
|
||||
<string name="access_code_alert_validation_description">Votre code d\'accès sera utilisé pour déverrouiller votre portefeuille et protéger l\'accès à vos actifs.</string>
|
||||
<string name="access_code_alert_validation_ok">Utiliser quand même</string>
|
||||
<string name="access_code_alert_validation_title">Ce code d\'accès peut être facilement deviné.</string>
|
||||
<string name="access_code_check_title">Entrez le code d\'accès</string>
|
||||
<string name="access_code_check_warining_delete">Code d\'accès incorrect. Votre portefeuille mobile sera supprimé après %s tentatives incorrectes supplémentaires.</string>
|
||||
<string name="access_code_check_warining_lock">Code d\'accès incorrect. L\'application sera verrouillée après %s tentatives infructueuses supplémentaires.</string>
|
||||
<string name="access_code_check_warining_wait">Code d\'accès incorrect.\nVeuillez patienter %s secondes et réessayer.</string>
|
||||
<string name="access_code_confirm_description">Confirmez votre code d\'accès pour continuer</string>
|
||||
<string name="access_code_confirm_title">Saisissez à nouveau le code d\'accès</string>
|
||||
<string name="access_code_create_description">Définissez un code d\'accès à %s chiffres pour déverrouiller votre portefeuille.</string>
|
||||
<string name="access_code_create_title">Créer un code d\'accès</string>
|
||||
<string name="access_code_navtitle">Code d\'accès</string>
|
||||
<string name="action_buttons_buy_empty_search_message">Jeton non trouvé dans votre portefeuille ? Consultez les marchés pour le trouver et l\'ajouter à l\'achat</string>
|
||||
<string name="action_buttons_sell_empty_search_message">Jeton non trouvé dans votre portefeuille ? Consultez les marchés pour le trouver et l\'ajouter à la vente</string>
|
||||
<string name="action_buttons_sell_navigation_bar_title">Vendre</string>
|
||||
|
|
@ -34,12 +50,16 @@
|
|||
<string name="alert_manage_tokens_unsupported_message">Les jetons du réseau %1$s ne sont pas pris en charge par cette carte en raison d\'une limitation du micrologiciel.</string>
|
||||
<string name="alert_troubleshooting_scan_card_title">Avez-vous des difficultés à scanner votre carte ?</string>
|
||||
<string name="alert_unsupported_card">Cette carte n\'est pas conçue pour fonctionner avec Tangem</string>
|
||||
<string name="app_settings_access_code_warning">Définissez d\'abord un code d\'accès pour activer la biométrie.</string>
|
||||
<string name="app_settings_default_fee">Frais par défaut</string>
|
||||
<string name="app_settings_default_fee_footer">Activez les frais par défaut pour définir automatiquement les frais de transaction et ignorer la page Frais lors de l\'envoi de fonds. Vous pouvez toujours revenir sur cette page si nécessaire.</string>
|
||||
<string name="app_settings_enable_biometrics_description">Accédez aux paramètres pour activer l\'authentification biométrique dans l\'application Tangem</string>
|
||||
<string name="app_settings_enable_biometrics_title">Activer l\'authentification biométrique</string>
|
||||
<string name="app_settings_off_require_access_code_alert_message">Le code d\'accès à votre portefeuille vous sera demandé ultérieurement afin que nous puissions le stocker en toute sécurité pour une utilisation future.</string>
|
||||
<string name="app_settings_off_saved_access_code_alert_message">Cela supprimera tous les codes d\'accès des portefeuilles enregistrés. Toute opération ultérieure avec le portefeuille nécessitera la soumission du code d\'accès.</string>
|
||||
<string name="app_settings_off_saved_wallet_alert_message">La suppression de la carte enregistrée supprime de l\'application tous les portefeuilles enregistrés et leurs codes d\'accès.</string>
|
||||
<string name="app_settings_on_require_access_code_alert_message">Cela supprimera tous les codes d\'accès enregistrés pour le portefeuille. Toute interaction ultérieure avec le portefeuille nécessitera la saisie du code d\'accès.</string>
|
||||
<string name="app_settings_require_access_code_footer">Cette option désactive la biométrie pour les actions sensibles. Vous devrez saisir votre code d\'accès à chaque fois que vous signerez une transaction.</string>
|
||||
<string name="app_settings_saved_access_codes">Enregistrer le code d\'accès</string>
|
||||
<string name="app_settings_saved_access_codes_footer">L\'authentification biométrique sera demandée à la place du code d\'accès pour les interactions avec votre carte.</string>
|
||||
<string name="app_settings_saved_wallet">Conserver le portefeuille dans l\'application</string>
|
||||
|
|
@ -49,6 +69,9 @@
|
|||
<string name="app_settings_theme_mode_system">Par défaut du système</string>
|
||||
<string name="app_settings_theme_selector_title">Thème</string>
|
||||
<string name="app_settings_title">Paramètres de l\'application</string>
|
||||
<string name="auth_info_add_wallet_title">Ajouter un wallet</string>
|
||||
<string name="auth_info_subtitle">Sélectionnez un wallet pour vous connecter</string>
|
||||
<string name="auth_info_title">Heureux de te revoir!</string>
|
||||
<string name="backup_complete_seed_description">Ces mots ne peuvent pas être récupérés en cas de perte. Assurez-vous de les conserver en lieu sûr.</string>
|
||||
<string name="balance_hidden_description">Pour masquer ou afficher vos soldes, il suffit de retourner l\'écran de votre appareil vers le bas ou de le désactiver dans les paramètres</string>
|
||||
<string name="balance_hidden_do_not_show_button">Ne plus afficher</string>
|
||||
|
|
@ -56,10 +79,17 @@
|
|||
<string name="balance_hidden_title">Les soldes sont masqués</string>
|
||||
<string name="beta_mode_warning_message">Selon les développeurs de la blockchain, les jetons Kaspa sont actuellement en version bêta. Restez à l\'écoute des mises à jour !</string>
|
||||
<string name="beta_mode_warning_title">Mode bêta</string>
|
||||
<string name="biometric_disabled_warning_description">La biométrie est désactivée sur votre appareil, vous ne pouvez donc pas l\'utiliser pour déverrouiller vos portefeuilles. Activez la biométrie dans les paramètres de votre appareil pour pouvoir à nouveau utiliser cette méthode.</string>
|
||||
<string name="biometric_disabled_warning_title">Authentification biométrique désactivée</string>
|
||||
<string name="biometric_lockout_permanent_warning_description">Veuillez scanner la carte/bague</string>
|
||||
<string name="biometric_lockout_permanent_warning_description_2">Vous avez atteint la limite de tentatives biométriques. Veuillez déverrouiller votre portefeuille en tapotant votre appareil ou en saisissant votre code d\'accès.</string>
|
||||
<string name="biometric_lockout_permanent_warning_title">Authentification biométrique verrouillée</string>
|
||||
<string name="biometric_lockout_warning_description">Veuillez réessayer dans 30 secondes ou scannez la carte/bague</string>
|
||||
<string name="biometric_lockout_warning_description_2">La connexion biométrique est temporairement verrouillée. Veuillez réessayer dans 30 secondes ou déverrouiller votre portefeuille à l\'aide d\'un appareil ou d\'un code d\'accès.</string>
|
||||
<string name="biometric_lockout_warning_title">Trop de tentatives</string>
|
||||
<string name="biometric_unavailable_warning">Vous avez désactivé l\'authentification biométrique sur votre téléphone et ne pourrez pas enregistrer de portefeuilles dans l\'application. Pour enregistrer des portefeuilles, veuillez activer la fonction d\'authentification biométrique dans les paramètres de votre téléphone.</string>
|
||||
<string name="biometric_updated_warning_description">Les données biométriques de votre appareil ont été mises à jour. Veuillez sélectionner votre portefeuille et saisir son code d\'accès pour réactiver la connexion biométrique.</string>
|
||||
<string name="biometric_updated_warning_title">Attention requise</string>
|
||||
<string name="bitcoin_promo_activation_error">Une erreur s\'est produite lors du traitement de votre code promo. Veuillez réessayer plus tard.</string>
|
||||
<string name="bitcoin_promo_activation_error_title">Erreur d\'activation</string>
|
||||
<string name="bitcoin_promo_activation_success">Votre code promotionnel a été activé avec succès. Une récompense sera créditée sur votre compte dans un délai de 14 jours.</string>
|
||||
|
|
@ -80,6 +110,13 @@
|
|||
<item quantity="one">%s token</item>
|
||||
<item quantity="other">%s tokens</item>
|
||||
</plurals>
|
||||
<string name="card_reset_alert_continue_message">Veuillez réinitialiser l\'appareil suivant pour continuer.</string>
|
||||
<string name="card_reset_alert_continue_title">Réinitialisation du portefeuille</string>
|
||||
<string name="card_reset_alert_finish_message">Tous les appareils Tangem ont été réinitialisés. Vous pouvez maintenant continuer à mettre à jour votre portefeuille.</string>
|
||||
<string name="card_reset_alert_finish_ok_button">Mettre de nouveau à jour</string>
|
||||
<string name="card_reset_alert_finish_title">Réinitialisation terminée</string>
|
||||
<string name="card_reset_alert_incomplete_message">Nous vous recommandons d\'effectuer la réinitialisation de tous les appareils Tangem contenus dans ce portefeuille.</string>
|
||||
<string name="card_reset_alert_incomplete_title">Vous n\'avez pas réinitialisé tous vos appareils Tangem.</string>
|
||||
<string name="card_settings_access_code_recovery_disabled_description">Désactivez cette option si vous ne voulez pas que cette carte soit utilisée pour réinitialiser les codes d\'accès sur d\'autres cartes de ce portefeuille. Veuillez noter que cela vous empêchera également de réinitialiser le code d\'accès sur cette carte.</string>
|
||||
<string name="card_settings_access_code_recovery_enabled_description">Vous permet d\'utiliser cette carte pour réinitialiser le code d\'accès sur d\'autres cartes de ce portefeuille</string>
|
||||
<string name="card_settings_access_code_recovery_title">Récupération du code d\'accès</string>
|
||||
|
|
@ -105,19 +142,25 @@
|
|||
<string name="cardano_max_amount_has_token_title">ADA insuffisant</string>
|
||||
<string name="common_accept">Accepter</string>
|
||||
<string name="common_access_denied">Accès refusé</string>
|
||||
<string name="common_account">Compte</string>
|
||||
<string name="common_accounts">Comptes</string>
|
||||
<string name="common_activate">Activer</string>
|
||||
<string name="common_add">Ajouter</string>
|
||||
<string name="common_add_to_portfolio">Ajouter au portfolio</string>
|
||||
<string name="common_add_token">Ajouter un jeton</string>
|
||||
<string name="common_added">Ajouté</string>
|
||||
<string name="common_address">Adresse</string>
|
||||
<string name="common_all">Tous</string>
|
||||
<string name="common_allow">Permettre</string>
|
||||
<string name="common_amount">Montant</string>
|
||||
<string name="common_analytics">Analytique</string>
|
||||
<string name="common_and">et</string>
|
||||
<string name="common_apply">Appliquer</string>
|
||||
<string name="common_approval">Approbation</string>
|
||||
<string name="common_approve">Approuver</string>
|
||||
<string name="common_attention">Attention</string>
|
||||
<string name="common_available_networks">Réseaux disponibles</string>
|
||||
<string name="common_backup">Sauvegarde</string>
|
||||
<string name="common_balance">Solde : %s</string>
|
||||
<string name="common_balance_title">Solde</string>
|
||||
<string name="common_biometric_authentication">authentification biométrique</string>
|
||||
|
|
@ -128,6 +171,7 @@
|
|||
<string name="common_camera_denied_alert_message">Vous n\'avez pas octroyé l\'accès à votre caméra, veuillez modifier vos paramètres de confidentialité</string>
|
||||
<string name="common_cancel">Annuler</string>
|
||||
<string name="common_change">Changez</string>
|
||||
<string name="common_choose_account">Choisissez un compte</string>
|
||||
<string name="common_choose_action">Choisissez une action</string>
|
||||
<string name="common_choose_network">Choisissez le réseau</string>
|
||||
<string name="common_choose_token">Choisir le jeton</string>
|
||||
|
|
@ -135,8 +179,12 @@
|
|||
<string name="common_claim">Réclamer</string>
|
||||
<string name="common_claim_rewards">Réclamez des récompenses</string>
|
||||
<string name="common_close">Fermer</string>
|
||||
<string name="common_coming_soon">À venir</string>
|
||||
<string name="common_confirm">Confirmez</string>
|
||||
<string name="common_connecting">Connexion</string>
|
||||
<string name="common_contact_support">Contactez l\'équipe de support</string>
|
||||
<string name="common_contact_tangem_support">Contacter l\'assistance Tangem</string>
|
||||
<string name="common_contact_visa_support">Contacter le service d\'assistance Visa</string>
|
||||
<string name="common_continue">Continuer</string>
|
||||
<string name="common_convert">Convertir</string>
|
||||
<string name="common_copy">Copier</string>
|
||||
|
|
@ -153,6 +201,7 @@
|
|||
<item quantity="other">jours</item>
|
||||
</plurals>
|
||||
<string name="common_delete">Supprimer</string>
|
||||
<string name="common_disable">Désactiver</string>
|
||||
<string name="common_disabled">Désactivé</string>
|
||||
<string name="common_disconnect">Se déconnecter</string>
|
||||
<string name="common_done">Exécuté</string>
|
||||
|
|
@ -172,9 +221,13 @@
|
|||
<string name="common_fee_selector_option_slow">Lent</string>
|
||||
<string name="common_fee_selector_title">Vitesse et frais</string>
|
||||
<string name="common_finish">Terminer</string>
|
||||
<string name="common_forget">Oublier</string>
|
||||
<string name="common_free">Gratuit</string>
|
||||
<string name="common_from">Du</string>
|
||||
<string name="common_from_wallet_name">De %s</string>
|
||||
<string name="common_generate_addresses">Synchroniser les adresses</string>
|
||||
<string name="common_get_started">Commencer</string>
|
||||
<string name="common_get_token">Obtenir un token</string>
|
||||
<string name="common_go_to_provider">Aller au fournisseur</string>
|
||||
<string name="common_go_to_token">Aller au jeton</string>
|
||||
<string name="common_got_it">Compris</string>
|
||||
|
|
@ -185,16 +238,25 @@
|
|||
<string name="common_later">Plus tard</string>
|
||||
<string name="common_learn_more">En savoir plus</string>
|
||||
<string name="common_left">Il reste %1$s</string>
|
||||
<string name="common_legacy_bitcoin_address">Legacy Bitcoin</string>
|
||||
<string name="common_locked">Verrouillé</string>
|
||||
<string name="common_locked_wallets">Portefeuilles verrouillés</string>
|
||||
<string name="common_main_network">Réseau principal</string>
|
||||
<string name="common_month">mois</string>
|
||||
<string name="common_network_fee_title">Commissions du réseau</string>
|
||||
<string name="common_network_fee_warning_content">Le montant envoyé sera réduit de %1$s(%2$s) pour couvrir le niveau de frais sélectionné</string>
|
||||
<plurals name="common_networks_count">
|
||||
<item quantity="one">%d réseau</item>
|
||||
<item quantity="other">%d réseaux</item>
|
||||
</plurals>
|
||||
<string name="common_new_address">Nouvelle adresse</string>
|
||||
<string name="common_news">Actualités</string>
|
||||
<string name="common_next">Suivant</string>
|
||||
<string name="common_nft">NFT</string>
|
||||
<string name="common_no">Non</string>
|
||||
<string name="common_no_address">Aucune adresse</string>
|
||||
<string name="common_not_added">Non ajouté</string>
|
||||
<string name="common_not_now">Pas maintenant</string>
|
||||
<string name="common_now">Maintenant</string>
|
||||
<string name="common_ok">OK</string>
|
||||
<string name="common_open_in_browser">Ouvrir dans le navigateur</string>
|
||||
|
|
@ -207,10 +269,12 @@
|
|||
<string name="common_range_with_space">%1$s — %2$s</string>
|
||||
<string name="common_read_more">En savoir plus</string>
|
||||
<string name="common_receive">Recevoir</string>
|
||||
<string name="common_recommended">Recommandé</string>
|
||||
<string name="common_reject">Rejeter</string>
|
||||
<string name="common_reload">Recharger</string>
|
||||
<string name="common_rename">Renommer</string>
|
||||
<string name="common_required">Obligatoire</string>
|
||||
<string name="common_reset">Réinitialiser</string>
|
||||
<string name="common_save">Enregistrez</string>
|
||||
<string name="common_save_changes">Sauvegarder les modifications</string>
|
||||
<string name="common_search">Rechercher</string>
|
||||
|
|
@ -229,6 +293,8 @@
|
|||
<string name="common_show_more">Afficher plus</string>
|
||||
<string name="common_sign">Signez</string>
|
||||
<string name="common_sign_and_send">Signez et envoyez</string>
|
||||
<string name="common_skip">Passer</string>
|
||||
<string name="common_something_went_wrong">Une erreur s\'est produite.</string>
|
||||
<string name="common_stake">Stake</string>
|
||||
<string name="common_staking">Staking</string>
|
||||
<string name="common_start">Démarrer</string>
|
||||
|
|
@ -237,18 +303,22 @@
|
|||
<string name="common_support">Support</string>
|
||||
<string name="common_supported_networks">Réseaux pris en charge</string>
|
||||
<string name="common_swap">Échanger</string>
|
||||
<string name="common_tangem">Tangem</string>
|
||||
<string name="common_tangem_wallet">Tangem Wallet</string>
|
||||
<string name="common_terms_and_conditions">termes et conditions</string>
|
||||
<string name="common_terms_of_use">Conditions d\'utilisation</string>
|
||||
<string name="common_to">À</string>
|
||||
<string name="common_to_wallet_name">À %s</string>
|
||||
<string name="common_today">Aujourd\'hui</string>
|
||||
<plurals name="common_tokens_count">
|
||||
<item quantity="one">%d jeton</item>
|
||||
<item quantity="other">%d jetons</item>
|
||||
<item quantity="one">%d token</item>
|
||||
<item quantity="other">%d tokens</item>
|
||||
</plurals>
|
||||
<string name="common_transaction_failed">La transaction a échoué</string>
|
||||
<string name="common_transaction_status">Statut de la transaction</string>
|
||||
<string name="common_transactions">Transactions</string>
|
||||
<string name="common_transfer">Fourniture</string>
|
||||
<string name="common_unable_to_load">Impossible de charger les données…</string>
|
||||
<string name="common_understand">Je comprends</string>
|
||||
<string name="common_unknown_error">Il y avait une erreur. Veuillez réessayer.</string>
|
||||
<string name="common_unreachable">Inaccessible</string>
|
||||
|
|
@ -300,7 +370,6 @@
|
|||
<string name="details_row_description_flip_to_hide">Retournez l\'écran de votre appareil vers le bas pour masquer et afficher rapidement les soldes</string>
|
||||
<string name="details_row_subtitle_signed_hashes_format">%s hashes</string>
|
||||
<string name="details_row_title_cid">ID de l\'appareil</string>
|
||||
<string name="details_row_title_contact_to_support">Contactez l\'équipe de support</string>
|
||||
<string name="details_row_title_contact_to_support_chat">Ouvrir le chat d\'assistance</string>
|
||||
<string name="details_row_title_create_backup">Lier plus de cartes</string>
|
||||
<string name="details_row_title_currency">Monnaie de l\'application</string>
|
||||
|
|
@ -422,8 +491,10 @@
|
|||
<string name="home_button_create_new_wallet">Créer un nouveau Portefeuille</string>
|
||||
<string name="home_button_order">Commandez</string>
|
||||
<string name="home_button_scan">Scannez</string>
|
||||
<string name="hot_access_code_set_biometric_ask">Souhaitez-vous autoriser « Tangem » à utiliser l\'authentification biométrique ? Pour confirmer votre identité et ouvrir l\'application</string>
|
||||
<string name="hot_crypto_add_token_subtitle">à %s</string>
|
||||
<string name="hot_crypto_token_network">Via %s</string>
|
||||
<string name="hw_access_code_create_alert_title">Êtes-vous sûr de vouloir annuler la configuration du code d\'accès ?</string>
|
||||
<string name="information_generated_with_ai">Ces informations ont été générées avec l\'IA.\nAppuyez ici si vous trouvez des erreurs.</string>
|
||||
<string name="initial_message_change_access_code_body">Touchez, pour modifier le code d\'accès</string>
|
||||
<string name="initial_message_change_passcode_body">Touchez, pour modifier le mot de passe</string>
|
||||
|
|
@ -477,11 +548,13 @@
|
|||
<string name="markets_apy_placeholder">APY %s</string>
|
||||
<string name="markets_common_my_portfolio">Mon portfolio</string>
|
||||
<string name="markets_common_title">Marché</string>
|
||||
<string name="markets_earn_common_title">Gagnez avec Tangem</string>
|
||||
<string name="markets_generate_addresses_notification">Pour générer des adresses pour les réseaux sélectionnés, vous devez scanner votre carte Tangem</string>
|
||||
<string name="markets_hint">Pour ajouter des jetons, faites-le apparaître ou appuyez sur la barre de recherche</string>
|
||||
<string name="markets_insights_info_description_message">Les données de cette section proviennent des réseaux suivants : %s</string>
|
||||
<string name="markets_loading_error_title">Impossible de charger les données…</string>
|
||||
<string name="markets_loading_no_data_title">Aucune donnée</string>
|
||||
<string name="markets_pulse_common_title">Rythme du marché</string>
|
||||
<string name="markets_quick_actions">Actions rapides</string>
|
||||
<string name="markets_search_header_title">Rechercher sur le marché</string>
|
||||
<string name="markets_search_result_title">Résultat</string>
|
||||
|
|
@ -571,6 +644,10 @@
|
|||
<string name="markets_token_details_volume">Volume</string>
|
||||
<string name="markets_tooltip_message">Tirez vers le haut ou appuyez sur la barre de recherche pour ajouter des jetons directement depuis le marché</string>
|
||||
<string name="markets_tooltip_title">Ajouter des jetons</string>
|
||||
<string name="markets_yield_supply_banner_description">Optimisez vos actifs tout en leur fournissant un accès instantané. %s</string>
|
||||
<string name="markets_yield_supply_banner_title">Activer le mode rendement</string>
|
||||
<string name="mobile_wallet_requires_min_os_warning_body">Vous devez effectuer la mise à jour %1$s afin de créer un portefeuille mobile.</string>
|
||||
<string name="mobile_wallet_requires_min_os_warning_title">Le portefeuille mobile nécessite %1$s ou une version supérieure.</string>
|
||||
<string name="nfc_error_unavailable">NFC n\'est pas disponible sur votre appareil</string>
|
||||
<string name="nft_about_title">À propos des NFT</string>
|
||||
<string name="nft_asset">Actif NFT</string>
|
||||
|
|
@ -627,6 +704,9 @@
|
|||
<string name="no_trustline_xlm_asset">Le compte destinataire n\'a pas de Trustline pour l\'actif envoyé qu\'il tente d\'envoyer.</string>
|
||||
<string name="notification_black_friday_text">Obtenez 10 $ en BTC avec chaque wallet\nDépêchez-vous !</string>
|
||||
<string name="notification_black_friday_title">Black Friday : jusqu\'à 30% de réduction</string>
|
||||
<string name="notification_one_plus_one_button">C\'est parti !</string>
|
||||
<string name="notification_one_plus_one_text">Offre à durée limitée !</string>
|
||||
<string name="notification_one_plus_one_title">1 + 1 : achetez 1 wallet et bénéficiez de 50 % de réduction sur le 2ᵉ</string>
|
||||
<string name="notification_referral_promo_button">Rejoignez maintenant</string>
|
||||
<string name="notification_referral_promo_text">Partagez votre code et gagnez 5 USDT par vente. Votre ami bénéficie de 10 % de réduction.</string>
|
||||
<string name="notification_referral_promo_title">Recevez des RÉCOMPENSES pour chaque ami !</string>
|
||||
|
|
@ -1126,6 +1206,111 @@
|
|||
<string name="swapping_to_title">Vous recevez</string>
|
||||
<string name="swapping_token_list_title">Choisir le jeton</string>
|
||||
<string name="swapping_token_not_available">non disponible</string>
|
||||
<string name="tangem_pay_beta_notification_subtitle">Nous serions ravis de recevoir vos retours</string>
|
||||
<string name="tangem_pay_beta_notification_title">Tangem Pay en version bêta</string>
|
||||
<string name="tangem_pay_card_frozen">Carte gelée</string>
|
||||
<string name="tangem_pay_card_payment">Paiement par carte</string>
|
||||
<string name="tangem_pay_deposit">Dépôt</string>
|
||||
<string name="tangem_pay_dispute">Litige</string>
|
||||
<string name="tangem_pay_explore_transaction">Explorer la transaction</string>
|
||||
<string name="tangem_pay_fee_subtitle">Frais de service</string>
|
||||
<string name="tangem_pay_fee_title">Frais</string>
|
||||
<string name="tangem_pay_freeze_card_alert_body">Protégez votre argent. Vous pouvez le débloquer à tout moment.</string>
|
||||
<string name="tangem_pay_freeze_card_alert_title">Geler votre carte ?</string>
|
||||
<string name="tangem_pay_freeze_card_failed">Échec du gel de la carte. Réessayez plus tard.</string>
|
||||
<string name="tangem_pay_freeze_card_freeze">Geler</string>
|
||||
<string name="tangem_pay_freeze_card_success">Votre carte est gelée.</string>
|
||||
<string name="tangem_pay_get_help">Obtenir de l\'aide</string>
|
||||
<string name="tangem_pay_other">Autre</string>
|
||||
<string name="tangem_pay_status_completed">Terminé</string>
|
||||
<string name="tangem_pay_status_declined">Refusé</string>
|
||||
<string name="tangem_pay_status_pending">En attente</string>
|
||||
<string name="tangem_pay_terms_fees_limits">Conditions, frais et limites</string>
|
||||
<string name="tangem_pay_terms_limits">Conditions et limites</string>
|
||||
<string name="tangem_pay_transaction_declined_notification_text">La banque a rejeté cette demande de transaction.</string>
|
||||
<string name="tangem_pay_transaction_fee_notification_text">Ces frais couvrent le coût du traitement de votre virement.</string>
|
||||
<string name="tangem_pay_unfreeze_card_alert_body">Continuez à utiliser votre argent. Vous pouvez le geler à tout moment.</string>
|
||||
<string name="tangem_pay_unfreeze_card_alert_title">Dégeler votre carte ?</string>
|
||||
<string name="tangem_pay_unfreeze_card_failed">Échec du dégel de la carte. Réessayez plus tard.</string>
|
||||
<string name="tangem_pay_unfreeze_card_success">Votre carte est dégelée.</string>
|
||||
<string name="tangem_pay_withdrawal">Retrait</string>
|
||||
<string name="tangempay_card_details_add_funds">Ajouter des fonds</string>
|
||||
<string name="tangempay_card_details_add_funds_subtitle">Options de recharge</string>
|
||||
<string name="tangempay_card_details_card_number">Numéro de carte</string>
|
||||
<string name="tangempay_card_details_change_pin">Modifier le code PIN</string>
|
||||
<string name="tangempay_card_details_change_pin_success_description">La carte est totalement prête pour les paiements.</string>
|
||||
<string name="tangempay_card_details_change_pin_success_title">Code PIN créé</string>
|
||||
<string name="tangempay_card_details_cvc">CVC</string>
|
||||
<string name="tangempay_card_details_error_text">Échec du chargement des données. Réessayez plus tard.</string>
|
||||
<string name="tangempay_card_details_expiry">Expiration</string>
|
||||
<string name="tangempay_card_details_freeze_card">Geler la carte</string>
|
||||
<string name="tangempay_card_details_hide_details">Masquer les détails</string>
|
||||
<string name="tangempay_card_details_hide_text">Masquer</string>
|
||||
<string name="tangempay_card_details_open_wallet_button">Ouvrir Google Wallet</string>
|
||||
<string name="tangempay_card_details_open_wallet_notification_subtitle">Configurez Tangem Pay en quelques clics et commencez à payer avec Google Pay.</string>
|
||||
<string name="tangempay_card_details_open_wallet_notification_subtitle_apple">Configurez Tangem Pay en quelques clics et commencez à payer avec Apple Pay</string>
|
||||
<string name="tangempay_card_details_open_wallet_notification_title">Ajoutez votre carte à Google Pay</string>
|
||||
<string name="tangempay_card_details_open_wallet_notification_title_apple">Ajouter votre carte à Apple Pay</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_1">Ouvrir Google Wallet</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_1_5_apple">Appuyez sur le bouton « + » en haut à droite</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_1_apple">Ouvrir Apple Wallet</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_2">Appuyez sur « Ajouter une carte »</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_2_apple">Appuyez sur « Carte de débit ou de crédit »</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_3">Saisissez manuellement les détails de la carte</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_4">Vérifiez la carte à l\'aide de l\'OTP envoyé à votre appareil.</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_5">Tout est prêt ! Votre carte est prête à l\'emploi.</string>
|
||||
<string name="tangempay_card_details_open_wallet_title">Ajouter une carte à Google Pay</string>
|
||||
<string name="tangempay_card_details_open_wallet_title_apple">Ajouter la carte à Apple Pay</string>
|
||||
<string name="tangempay_card_details_receive_description">Partagez votre adresse ou montrez le QR code</string>
|
||||
<string name="tangempay_card_details_receive_error_title">Réception indisponible pour le moment</string>
|
||||
<string name="tangempay_card_details_reveal_text">Révéler</string>
|
||||
<string name="tangempay_card_details_show_details">Afficher les détails</string>
|
||||
<string name="tangempay_card_details_swap_description">Échangez n\'importe quel actif de votre portefeuille contre une carte</string>
|
||||
<string name="tangempay_card_details_title">Détails de la carte</string>
|
||||
<string name="tangempay_card_details_unfreeze_card">Dégeler la carte</string>
|
||||
<string name="tangempay_card_details_withdraw">Retirer</string>
|
||||
<string name="tangempay_card_details_withdraw_error_title">Retrait indisponible pour le moment</string>
|
||||
<string name="tangempay_card_details_withdraw_in_progress_description">Vous ne pouvez pas lancer d\'échange ou de nouveau retrait tant que le retrait actuel n\'est pas terminé.</string>
|
||||
<string name="tangempay_card_details_withdraw_in_progress_title">Retrait en cours</string>
|
||||
<string name="tangempay_change_pin_code">Modifier le code PIN</string>
|
||||
<string name="tangempay_come_back_if_forget_pin">Revenez dans l\'application si vous l\'oubliez.</string>
|
||||
<string name="tangempay_failed_to_issue_card">Échec de l\'émission de la carte</string>
|
||||
<string name="tangempay_failed_to_issue_card_retry_description">Une erreur technique s\'est produite, veuillez réessayer en cliquant sur le bouton ci-dessous</string>
|
||||
<string name="tangempay_failed_to_issue_card_support_description">Une erreur technique s\'est produite, veuillez contacter le support</string>
|
||||
<string name="tangempay_get_banner_description">Utilisez vos cryptomonnaies pour vos dépenses quotidiennes. \nC\'est une carte de paiement unique en son genre.</string>
|
||||
<string name="tangempay_get_tangem_pay">Obtenir Tangem Pay</string>
|
||||
<string name="tangempay_go_to_support">Contacter le support</string>
|
||||
<string name="tangempay_issue_card_notification_description">Cela prend généralement jusqu\'à 15 minutes</string>
|
||||
<string name="tangempay_issue_card_notification_title">Configuration de votre carte Tangem</string>
|
||||
<string name="tangempay_issuing_your_card">Émission de votre carte</string>
|
||||
<string name="tangempay_issuing_your_card_description">Nous préparons votre carte. Cela peut prendre un peu de temps.</string>
|
||||
<string name="tangempay_kyc_card_ready_notification_title">Tangem Pay</string>
|
||||
<string name="tangempay_kyc_failed_description">Nous n\'avons pas pu vérifier votre profil. Pour toute question, veuillez contacter le support.</string>
|
||||
<string name="tangempay_kyc_failed_title">Malheureusement, nous n\'avons pas pu vérifier votre identité</string>
|
||||
<string name="tangempay_kyc_in_progress">KYC en cours</string>
|
||||
<string name="tangempay_kyc_in_progress_notification_button">Voir le statut</string>
|
||||
<string name="tangempay_kyc_in_progress_notification_title">KYC en cours pour Tangem Pay</string>
|
||||
<string name="tangempay_onboarding_banner_description">Utilisez vos cryptomonnaies pour vos dépenses du quotidien. \nC\'est une carte de paiement unique en son genre.</string>
|
||||
<string name="tangempay_onboarding_banner_title">Tangem Visa Card</string>
|
||||
<string name="tangempay_onboarding_get_card_button_text">Obtenir la carte</string>
|
||||
<string name="tangempay_onboarding_pay_description">Avec carte numérique compatible Apple Pay et Google Pay</string>
|
||||
<string name="tangempay_onboarding_pay_title">Dépensez vos actifs partout</string>
|
||||
<string name="tangempay_onboarding_purchases_description">Aucuns frais supplémentaires pour les achats</string>
|
||||
<string name="tangempay_onboarding_purchases_title">Payez exactement ce que vous voyez</string>
|
||||
<string name="tangempay_onboarding_security_description">Un compte de paiement séparé sera créé sans divulguer vos adresses et actifs</string>
|
||||
<string name="tangempay_onboarding_security_title">Confidentialité inégalée</string>
|
||||
<string name="tangempay_onboarding_title">Obtenez votre carte Tangem Pay gratuite en quelques minutes</string>
|
||||
<string name="tangempay_payment_account">Payment account</string>
|
||||
<string name="tangempay_payment_account_sync_needed">Synchronisation du compte de paiement nécessaire</string>
|
||||
<string name="tangempay_service_unavailable_description">Nous réparons un problème technique. Veuillez réessayer plus tard.</string>
|
||||
<string name="tangempay_service_unavailable_title">Service temporairement indisponible</string>
|
||||
<string name="tangempay_service_unreachable_try_later">Le service est actuellement indisponible. Veuillez réessayer plus tard.</string>
|
||||
<string name="tangempay_sync_needed">Synchronisation requise</string>
|
||||
<string name="tangempay_tangem_visa_card">Tangem Visa Card</string>
|
||||
<string name="tangempay_temporarily_unavailable">Tangem Pay est temporairement indisponible</string>
|
||||
<string name="tangempay_title">Tangem Pay</string>
|
||||
<string name="tangempay_use_tangem_device_to_restore_payment_account">Utilisez votre carte ou votre bague pour restaurer l\'accès à votre compte de paiement</string>
|
||||
<string name="tangempay_your_pin_code">Votre code PIN</string>
|
||||
<string name="this_is_my_wallet_title">C\'est mon portefeuille</string>
|
||||
<string name="toast_balances_hidden">Soldes masqués</string>
|
||||
<string name="toast_balances_shown">Soldes affichés</string>
|
||||
|
|
@ -1217,6 +1402,8 @@
|
|||
<item quantity="other">disponible pour %d jours</item>
|
||||
</plurals>
|
||||
<string name="visa_main_balances_and_limits">Soldes et Limites</string>
|
||||
<string name="visa_onboarding_access_code_description">Le code d\'accès sera utilisé pour gérer votre compte de paiement et le protéger contre tout accès non autorisé.</string>
|
||||
<string name="visa_onboarding_access_code_navigation_title">Code d\'accès</string>
|
||||
<string name="visa_onboarding_close_alert_message">Êtes-vous sûr de vouloir quitter ? Vous pourrez reprendre plus tard là où vous vous étiez arrêté.</string>
|
||||
<string name="visa_onboarding_in_progress_description">Cela ne prendra pas longtemps. Nous configurons votre compte.</string>
|
||||
<string name="visa_onboarding_in_progress_issuer_description">Cela ne prendra pas longtemps. Nous terminons l\'activation.</string>
|
||||
|
|
@ -1230,6 +1417,7 @@
|
|||
<string name="visa_unlock_notification_button">Déverrouiller</string>
|
||||
<string name="visa_unlock_notification_subtitle">Scannez votre carte pour déverrouiller l\'accès</string>
|
||||
<string name="visa_unlock_notification_title">Déverrouillage nécessaire</string>
|
||||
<string name="wallet_add_common_title">Choisissez comment ajouter votre portefeuille</string>
|
||||
<string name="wallet_balance_blockchain_unreachable_try_later">La blockchain n\'est pas accessible. Réessayez plus tard</string>
|
||||
<string name="wallet_balance_missing_derivation">Scanner la carte ou la bague</string>
|
||||
<string name="wallet_been_activated_message">Ce portefeuille a déjà été activé auparavant.\nSi cela n\'a pas été fait par vous, veuillez contacter le support.\nTangem ne vend jamais de portefeuilles avec le code d\'accès pré-généré.</string>
|
||||
|
|
@ -1265,6 +1453,21 @@
|
|||
<string name="wallet_connect_subtitle">Se connecter aux dApps</string>
|
||||
<string name="wallet_connect_title">WalletConnect</string>
|
||||
<string name="wallet_connect_toast_awaiting_session_proposal">La connexion peut prendre quelques secondes</string>
|
||||
<string name="wallet_create_common_title">Créer un Tangem Wallet</string>
|
||||
<string name="wallet_import_buy_question">Vous souhaitez acheter le Tangem Wallet ?</string>
|
||||
<string name="wallet_import_buy_title">Acheter maintenant</string>
|
||||
<string name="wallet_import_google_drive_description">Récupérer un portefeuille existant via la sauvegarde Google Drive</string>
|
||||
<string name="wallet_import_google_drive_title">Importer depuis Google Drive</string>
|
||||
<string name="wallet_import_navtitle">Ajouter un portefeuille existant</string>
|
||||
<string name="wallet_import_scan_description">Dispositifs physiques qui stockent votre clé privée hors ligne en toute sécurité.</string>
|
||||
<string name="wallet_import_scan_title">Scanner un Tangem Wallet</string>
|
||||
<string name="wallet_import_seed_description">Importez un portefeuille existant à l\'aide de votre seedphrase.</string>
|
||||
<string name="wallet_import_seed_navtitle">Importer un wallet</string>
|
||||
<string name="wallet_import_seed_title">Entrez la seedphrase</string>
|
||||
<string name="wallet_import_success_description">Vous avez sauvegardé votre portefeuille avec succès.</string>
|
||||
<string name="wallet_import_success_navtitle">Importer un wallet</string>
|
||||
<string name="wallet_import_success_title">Importation terminée</string>
|
||||
<string name="wallet_import_title">Importer un portefeuille</string>
|
||||
<string name="wallet_marketplace_block_title">%s Prix du marché</string>
|
||||
<string name="wallet_marketprice_block_update_time">dernières 24h</string>
|
||||
<string name="wallet_network_group_title">%s réseau</string>
|
||||
|
|
@ -1273,8 +1476,13 @@
|
|||
<string name="wallet_promo_banner_button_title">Obtenez-le maintenant avec 10 % de réduction</string>
|
||||
<string name="wallet_promo_banner_description">Accédez à plus de 13 000 cryptomonnaies. Achetez, vendez, échangez et stakez en un seul clic.\nAssociez jusqu\'à trois cartes pour une sauvegarde.</string>
|
||||
<string name="wallet_promo_banner_title">Découvrez le Portefeuille Tangem</string>
|
||||
<string name="wallet_settings_access_code_description">Ce code d\'accès protège votre portefeuille et sert à vous connecter et à signer des transactions.</string>
|
||||
<string name="wallet_settings_access_code_title">Définir/Modifier le code d\'accès</string>
|
||||
<string name="wallet_settings_change_access_code_title">Modifier le code d\'accès</string>
|
||||
<string name="wallet_settings_push_notifications_description">Recevez des notifications sur les transactions entrantes du portefeuille et les mises à jour de Tangem.</string>
|
||||
<string name="wallet_settings_push_notifications_huawei_warning">Les notifications push peuvent ne pas fonctionner actuellement sur les appareils Huawei. Nous travaillons activement à la résolution de ce problème et publierons un correctif dans une prochaine mise à jour. Merci de votre compréhension !</string>
|
||||
<string name="wallet_settings_push_notifications_title">Notifications de transaction</string>
|
||||
<string name="wallet_settings_set_access_code_title">Définir le code d\'accès</string>
|
||||
<string name="wallet_settings_title">Paramètres du portefeuille</string>
|
||||
<string name="wallet_title">Tangem</string>
|
||||
<string name="warning_access_denied_message">Utilisez %s ou scannez une carte/bague pour déverrouiller l\'accès à votre portefeuille</string>
|
||||
|
|
@ -1456,7 +1664,20 @@
|
|||
<string name="wc_transaction_request_title">Demande de transaction</string>
|
||||
<string name="wc_unlimited_amount">Montant illimité</string>
|
||||
<string name="wc_wallet_connect">WalletConnect</string>
|
||||
<string name="welcome_create_wallet_use_hardware_title">En savoir plus</string>
|
||||
<string name="welcome_create_wallet_already_have">Vous avez déjà un portefeuille Tangem ?</string>
|
||||
<string name="welcome_create_wallet_feature_assets">Des milliers d\'actifs</string>
|
||||
<string name="welcome_create_wallet_feature_class">Le meilleur hardware wallet de sa catégorie</string>
|
||||
<string name="welcome_create_wallet_feature_delivery">Livraison rapide</string>
|
||||
<string name="welcome_create_wallet_feature_one_tap">Commencez en un seul clic</string>
|
||||
<string name="welcome_create_wallet_feature_seamless">Sans faille et sécurisé</string>
|
||||
<string name="welcome_create_wallet_feature_use">Facile à utiliser</string>
|
||||
<string name="welcome_create_wallet_hardware_description">Créez un harware wallet avec Tangem. Aussi fin qu\'une carte bancaire, aussi sûr qu\'un coffre-fort.</string>
|
||||
<string name="welcome_create_wallet_mobile_description">Créer ou importer un portefeuille logiciel</string>
|
||||
<string name="welcome_create_wallet_mobile_description_full">Créez ou importez un portefeuille logiciel sur votre téléphone.</string>
|
||||
<string name="welcome_create_wallet_mobile_title">Commencez avec Mobile Wallet</string>
|
||||
<string name="welcome_create_wallet_other_method">Autre méthode</string>
|
||||
<string name="welcome_create_wallet_use_hardware_description">Utilisez le hardware wallet Tangem</string>
|
||||
<string name="welcome_create_wallet_use_hardware_title">En savoir plus et acheter</string>
|
||||
<string name="welcome_interrupted_backup_alert_discard">Ignorer</string>
|
||||
<string name="welcome_interrupted_backup_alert_message">Vous avez une sauvegarde interrompue. Voulez-vous la reprendre ?</string>
|
||||
<string name="welcome_interrupted_backup_alert_resume">Oui, reprendre</string>
|
||||
|
|
@ -1507,7 +1728,10 @@
|
|||
<string name="yield_module_fee_policy_sheet_title">Politique tarifaire</string>
|
||||
<string name="yield_module_fee_policy_tangem_service_fee_title">Tangem prélève également des frais de service de 15% sur les revenus générés.</string>
|
||||
<string name="yield_module_high_fee_error">Vos fonds seront automatiquement transférés vers Aave dès que les frais de réseau seront moins élevés ou que votre solde atteindra le montant minimum requis.</string>
|
||||
<string name="yield_module_high_network_fees_notification_description">Les frais sont plus élevés que d\'habitude car le marché est très actif. Vous pouvez procéder maintenant ou revenir plus tard lorsque les frais seront moins élevés.</string>
|
||||
<string name="yield_module_high_network_fees_notification_title">Frais de réseau élevés</string>
|
||||
<string name="yield_module_historical_returns">Rendements historiques</string>
|
||||
<string name="yield_module_main_screen_promo_banner_message">Activez %1$s%% APY sur votre solde</string>
|
||||
<string name="yield_module_main_view_approve_notification_description">L\'autorisation pour votre token en mode Rendement a été révoquée. Ouvrez le token pour accorder à nouveau l\'autorisation.</string>
|
||||
<string name="yield_module_main_view_approve_notification_title">Approbations de tokens nécessaires</string>
|
||||
<string name="yield_module_network_fee_unreachable_notification_description">Vérifiez votre connexion réseau.</string>
|
||||
|
|
@ -1522,7 +1746,9 @@
|
|||
<string name="yield_module_promo_screen_self_custodial_title">Décentralisé et auto-détenu</string>
|
||||
<string name="yield_module_promo_screen_terms_disclaimer">En utilisant ce service, vous acceptez les conditions générales du fournisseur %1$s et %2$s.</string>
|
||||
<string name="yield_module_promo_screen_title">Connecter Aave</string>
|
||||
<string name="yield_module_promo_screen_title_v2">Activez %1$s%% APY\nsur votre solde</string>
|
||||
<string name="yield_module_promo_screen_variable_rate_info">Aave %1$s%% • Taux d\'intérêt variable</string>
|
||||
<string name="yield_module_promo_screen_variable_rate_info_v2">Taux d\'intérêt variable</string>
|
||||
<string name="yield_module_provider">Aave</string>
|
||||
<string name="yield_module_rate_info_sheet_chart_average">Moyenne %s</string>
|
||||
<string name="yield_module_rate_info_sheet_chart_title">Rendements de l\'année dernière</string>
|
||||
|
|
@ -1541,6 +1767,7 @@
|
|||
<string name="yield_module_stop_earning_sheet_description">En désactivant cela, vos fonds seront retirés d\'Aave vers %s dans votre portefeuille et vous ne gagnerez plus de récompenses.</string>
|
||||
<string name="yield_module_stop_earning_sheet_fee_note">Des frais de réseau sont prélevés par la blockchain lorsque vous quittez le mode Yield.</string>
|
||||
<string name="yield_module_stop_earning_sheet_title">Désactiver le mode rendement</string>
|
||||
<string name="yield_module_supply">Réserves</string>
|
||||
<string name="yield_module_supply_apr">Rendement annuel brut (APY)</string>
|
||||
<string name="yield_module_token_details_earn_notification_apy">APY</string>
|
||||
<string name="yield_module_token_details_earn_notification_description">Les intérêts sont cumulés automatiquement.</string>
|
||||
|
|
@ -1548,12 +1775,16 @@
|
|||
<string name="yield_module_token_details_earn_notification_earning_on_your_balance_title">Mode Rendement</string>
|
||||
<string name="yield_module_token_details_earn_notification_processing">Traitement de votre dépôt</string>
|
||||
<string name="yield_module_token_details_earn_notification_title">Mode Rendement</string>
|
||||
<string name="yield_module_transaction_deploy_contract">Déployer le contrat du mode rendement</string>
|
||||
<string name="yield_module_transaction_enter">Mode rendement activé</string>
|
||||
<string name="yield_module_transaction_enter_subtitle">%1$s fourni à Aave</string>
|
||||
<string name="yield_module_transaction_exit">Mode rendement désactivé</string>
|
||||
<string name="yield_module_transaction_exit_subtitle">%1$s retiré d\'Aave</string>
|
||||
<string name="yield_module_transaction_initialize">Initialisation du mode de rendement</string>
|
||||
<string name="yield_module_transaction_reactivate">Réactiver le mode Rendement</string>
|
||||
<string name="yield_module_transaction_topup">Approvisionnement à Aave</string>
|
||||
<string name="yield_module_transaction_topup_subtitle">%1$s fourni à Aave</string>
|
||||
<string name="yield_module_transaction_withdraw">Retrait depuis Aave</string>
|
||||
<string name="yield_module_transfer_mode_automatic">Automatique</string>
|
||||
<string name="yield_module_unable_to_cover_fee_description">Déposez %1$s %2$s pour couvrir les frais de réseau liés aux transactions.</string>
|
||||
<string name="yield_module_unable_to_cover_fee_title">Impossible de couvrir les frais %s</string>
|
||||
|
|
|
|||
|
|
@ -68,6 +68,111 @@
|
|||
<string name="send_validation_invalid_amount">Importo non valido</string>
|
||||
<string name="send_validation_invalid_fee">La commissione supera il saldo</string>
|
||||
<string name="send_validation_invalid_total">Il totale supera il saldo</string>
|
||||
<string name="tangem_pay_beta_notification_subtitle">Saremo felici di ricevere il tuo feedback</string>
|
||||
<string name="tangem_pay_beta_notification_title">Tangem Pay ora in beta</string>
|
||||
<string name="tangem_pay_card_frozen">Carta congelata</string>
|
||||
<string name="tangem_pay_card_payment">Pagamento con carta</string>
|
||||
<string name="tangem_pay_deposit">Deposito</string>
|
||||
<string name="tangem_pay_dispute">Contestazione</string>
|
||||
<string name="tangem_pay_explore_transaction">Esplora transazione</string>
|
||||
<string name="tangem_pay_fee_subtitle">Commissioni</string>
|
||||
<string name="tangem_pay_fee_title">Commissione</string>
|
||||
<string name="tangem_pay_freeze_card_alert_body">Proteggi il tuo denaro. Puoi sbloccarlo in qualsiasi momento.</string>
|
||||
<string name="tangem_pay_freeze_card_alert_title">Bloccare la tua carta?</string>
|
||||
<string name="tangem_pay_freeze_card_failed">Impossibile congelare la carta. Riprova più tardi.</string>
|
||||
<string name="tangem_pay_freeze_card_freeze">Blocca</string>
|
||||
<string name="tangem_pay_freeze_card_success">La tua carta è congelata.</string>
|
||||
<string name="tangem_pay_get_help">Ottenere aiuto</string>
|
||||
<string name="tangem_pay_other">Altro</string>
|
||||
<string name="tangem_pay_status_completed">Completato</string>
|
||||
<string name="tangem_pay_status_declined">Rifiutato</string>
|
||||
<string name="tangem_pay_status_pending">In sospeso</string>
|
||||
<string name="tangem_pay_terms_fees_limits">Termini, commissioni e limiti</string>
|
||||
<string name="tangem_pay_terms_limits">Termini e limiti</string>
|
||||
<string name="tangem_pay_transaction_declined_notification_text">La banca ha rifiutato questa richiesta di transazione.</string>
|
||||
<string name="tangem_pay_transaction_fee_notification_text">Questa commissione copre il costo della gestione del tuo trasferimento.</string>
|
||||
<string name="tangem_pay_unfreeze_card_alert_body">Continua a usare i tuoi soldi. Puoi congelarli in qualsiasi momento.</string>
|
||||
<string name="tangem_pay_unfreeze_card_alert_title">Sbloccare la tua carta?</string>
|
||||
<string name="tangem_pay_unfreeze_card_failed">Impossibile sbloccare la carta. Riprova più tardi.</string>
|
||||
<string name="tangem_pay_unfreeze_card_success">La tua carta è sbloccata.</string>
|
||||
<string name="tangem_pay_withdrawal">Prelievo</string>
|
||||
<string name="tangempay_card_details_add_funds">Aggiungi fondi</string>
|
||||
<string name="tangempay_card_details_add_funds_subtitle">Opzioni di ricarica</string>
|
||||
<string name="tangempay_card_details_card_number">Numero carta</string>
|
||||
<string name="tangempay_card_details_change_pin">Modifica PIN</string>
|
||||
<string name="tangempay_card_details_change_pin_success_description">La carta è completamente pronta per i pagamenti.</string>
|
||||
<string name="tangempay_card_details_change_pin_success_title">Codice PIN creato</string>
|
||||
<string name="tangempay_card_details_cvc">CVC</string>
|
||||
<string name="tangempay_card_details_error_text">Impossibile caricare i dati. Riprova più tardi.</string>
|
||||
<string name="tangempay_card_details_expiry">Scadenza</string>
|
||||
<string name="tangempay_card_details_freeze_card">Blocca carta</string>
|
||||
<string name="tangempay_card_details_hide_details">Nascondi dettagli</string>
|
||||
<string name="tangempay_card_details_hide_text">Nascondi</string>
|
||||
<string name="tangempay_card_details_open_wallet_button">Apri Google Wallet</string>
|
||||
<string name="tangempay_card_details_open_wallet_notification_subtitle">Configura Tangem Pay in pochi tocchi e inizia a pagare con Google Pay.</string>
|
||||
<string name="tangempay_card_details_open_wallet_notification_subtitle_apple">Configura Tangem Pay in pochi tocchi e inizia a pagare con Apple Pay</string>
|
||||
<string name="tangempay_card_details_open_wallet_notification_title">Aggiungi la tua carta a Google Pay</string>
|
||||
<string name="tangempay_card_details_open_wallet_notification_title_apple">Aggiungi la tua carta ad Apple Pay</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_1">Apri Google Wallet</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_1_5_apple">Tocca il pulsante \"+\" in alto a destra</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_1_apple">Apri Apple Wallet</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_2">Tocca « Aggiungi una carta »</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_2_apple">Tocca “Carta di debito o di credito”</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_3">Inserisci manualmente i dettagli della carta</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_4">Verifica la carta utilizzando l\'OTP inviato al tuo dispositivo.</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_5">Tutto pronto! La tua carta è pronta per l\'uso.</string>
|
||||
<string name="tangempay_card_details_open_wallet_title">Aggiungi carta a Google Pay</string>
|
||||
<string name="tangempay_card_details_open_wallet_title_apple">Aggiungi carta ad Apple Pay</string>
|
||||
<string name="tangempay_card_details_receive_description">Condividi il tuo indirizzo o mostra il QR code</string>
|
||||
<string name="tangempay_card_details_receive_error_title">Ricezione non disponibile al momento</string>
|
||||
<string name="tangempay_card_details_reveal_text">Rivela</string>
|
||||
<string name="tangempay_card_details_show_details">Mostra dettagli</string>
|
||||
<string name="tangempay_card_details_swap_description">Scambia qualsiasi asset nel tuo portafoglio con una carta</string>
|
||||
<string name="tangempay_card_details_title">Dettagli carta</string>
|
||||
<string name="tangempay_card_details_unfreeze_card">Sblocca carta</string>
|
||||
<string name="tangempay_card_details_withdraw">Ritiro</string>
|
||||
<string name="tangempay_card_details_withdraw_error_title">Ritiro non disponibile ora</string>
|
||||
<string name="tangempay_card_details_withdraw_in_progress_description">Non puoi avviare uno swap o un nuovo prelievo finché quello attuale non è terminato</string>
|
||||
<string name="tangempay_card_details_withdraw_in_progress_title">Prelievo in corso</string>
|
||||
<string name="tangempay_change_pin_code">Cambia codice PIN</string>
|
||||
<string name="tangempay_come_back_if_forget_pin">Torna all\'app se lo dimentichi.</string>
|
||||
<string name="tangempay_failed_to_issue_card">Impossibile emettere la carta</string>
|
||||
<string name="tangempay_failed_to_issue_card_retry_description">Si è verificato un errore tecnico, riprova cliccando il pulsante qui sotto</string>
|
||||
<string name="tangempay_failed_to_issue_card_support_description">Si è verificato un errore tecnico, contatta il supporto</string>
|
||||
<string name="tangempay_get_banner_description">Utilizza le tue attività per fare acquisti nel mondo reale. \nÈ una carta di pagamento diversa da qualsiasi altra.</string>
|
||||
<string name="tangempay_get_tangem_pay">Ottieni Tangem Pay</string>
|
||||
<string name="tangempay_go_to_support">Vai al supporto</string>
|
||||
<string name="tangempay_issue_card_notification_description">Di solito richiede fino a 15 minuti</string>
|
||||
<string name="tangempay_issue_card_notification_title">Configurazione della tua carta Tangem</string>
|
||||
<string name="tangempay_issuing_your_card">Emissione della tua carta</string>
|
||||
<string name="tangempay_issuing_your_card_description">Stiamo preparando la tua carta. Ci vorrà un po\' di tempo.</string>
|
||||
<string name="tangempay_kyc_card_ready_notification_title">Tangem Pay</string>
|
||||
<string name="tangempay_kyc_failed_description">Non siamo riusciti a verificare il tuo profilo. Per domande, contatta il supporto.</string>
|
||||
<string name="tangempay_kyc_failed_title">Purtroppo non siamo riusciti a verificare la tua identità</string>
|
||||
<string name="tangempay_kyc_in_progress">KYC in corso</string>
|
||||
<string name="tangempay_kyc_in_progress_notification_button">Visualizza stato</string>
|
||||
<string name="tangempay_kyc_in_progress_notification_title">KYC in corso per Tangem Pay</string>
|
||||
<string name="tangempay_onboarding_banner_description">Utilizza le tue attività per fare acquisti nel mondo reale. \nÈ una carta di pagamento diversa da qualsiasi altra.</string>
|
||||
<string name="tangempay_onboarding_banner_title">Tangem Visa Card</string>
|
||||
<string name="tangempay_onboarding_get_card_button_text">Ottieni carta</string>
|
||||
<string name="tangempay_onboarding_pay_description">Con carta digitale che funziona con Apple Pay e Google Pay</string>
|
||||
<string name="tangempay_onboarding_pay_title">Spendi i tuoi asset ovunque</string>
|
||||
<string name="tangempay_onboarding_purchases_description">Non ci sono costi aggiuntivi per gli acquisti</string>
|
||||
<string name="tangempay_onboarding_purchases_title">Paga esattamente quello che vedi</string>
|
||||
<string name="tangempay_onboarding_security_description">Verrà creato un conto di pagamento separato senza divulgare i tuoi indirizzi e asset</string>
|
||||
<string name="tangempay_onboarding_security_title">Privacy senza rivali</string>
|
||||
<string name="tangempay_onboarding_title">Ottieni la tua carta Tangem Pay gratuita in pochi minuti</string>
|
||||
<string name="tangempay_payment_account">Payment account</string>
|
||||
<string name="tangempay_payment_account_sync_needed">Sincronizzazione del conto di pagamento necessaria</string>
|
||||
<string name="tangempay_service_unavailable_description">Stiamo risolvendo un problema tecnico. Riprova più tardi.</string>
|
||||
<string name="tangempay_service_unavailable_title">Servizio temporaneamente non disponibile</string>
|
||||
<string name="tangempay_service_unreachable_try_later">Il servizio è attualmente non raggiungibile. Riprova più tardi.</string>
|
||||
<string name="tangempay_sync_needed">Sincronizzazione necessaria</string>
|
||||
<string name="tangempay_tangem_visa_card">Tangem Visa Card</string>
|
||||
<string name="tangempay_temporarily_unavailable">Tangem Pay è temporaneamente non disponibile</string>
|
||||
<string name="tangempay_title">Tangem Pay</string>
|
||||
<string name="tangempay_use_tangem_device_to_restore_payment_account">Usa la tua carta o il tuo anello per ripristinare l\'accesso al tuo conto di pagamento</string>
|
||||
<string name="tangempay_your_pin_code">Il tuo codice PIN</string>
|
||||
<string name="twins_recreate_toolbar">Tangem Twin</string>
|
||||
<string name="wallet_connect_title">WalletConnect</string>
|
||||
<string name="wallet_notification_address_copied">L\'indirizzo è stato copiato con successo</string>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<string name="access_code_alert_skip_title">アクセスコードが設定されていません</string>
|
||||
<string name="access_code_alert_validation_cancel">コードを変更</string>
|
||||
<string name="access_code_alert_validation_description">アクセスコードは、ウォレットのロック解除・資産へのアクセス保護に使用されます</string>
|
||||
<string name="access_code_alert_validation_ok">このまま使用</string>
|
||||
<string name="access_code_alert_validation_ok">このまま使う</string>
|
||||
<string name="access_code_alert_validation_title">このアクセスコードは簡単に推測される可能性があります</string>
|
||||
<string name="access_code_check_title">アクセスコードを入力</string>
|
||||
<string name="access_code_check_warining_delete">アクセスコードが間違っています。あと%s回間違えると、モバイルウォレットが削除されます。</string>
|
||||
|
|
@ -144,7 +144,7 @@
|
|||
<string name="balance_hidden_title">残高は非表示</string>
|
||||
<string name="beta_mode_warning_message">ブロックチェーン開発者によると、Kaspaトークンは現在ベータ版です。アップデートをお楽しみに!</string>
|
||||
<string name="beta_mode_warning_title">ベータモード</string>
|
||||
<string name="biometric_disabled_warning_description">デバイスで生体認証がオフになっているため、ウォレットのロック解除に使用できません。\n生体認証を再度利用するには、デバイスの設定で有効にしてください。</string>
|
||||
<string name="biometric_disabled_warning_description">デバイスで生体認証がオフになっているため、ウォレットのロック解除に使用できません。生体認証を再度利用するには、デバイスの設定で有効にしてください。</string>
|
||||
<string name="biometric_disabled_warning_title">生体認証が無効になっています</string>
|
||||
<string name="biometric_lockout_permanent_warning_description">カードまたはリングをスキャンしてください</string>
|
||||
<string name="biometric_lockout_permanent_warning_description_2">生体認証の試行回数が上限に達しました。端末タップまたはアクセスコードでウォレットを解除してください。</string>
|
||||
|
|
@ -152,7 +152,7 @@
|
|||
<string name="biometric_lockout_warning_description">30秒後に再試行するか、カードまたはリングをスキャンしてください</string>
|
||||
<string name="biometric_lockout_warning_description_2">生体認証ログインは一時的にロックされています。30秒後にもう一度お試しいただくか、端末タップまたはアクセスコードでウォレットを解除してください。</string>
|
||||
<string name="biometric_lockout_warning_title">試行回数が多すぎます</string>
|
||||
<string name="biometric_unavailable_warning">お使いの携帯電話で生体認証が無効になっているため、アプリにウォレットを保存できません。ウォレットを保存するには、携帯電話の設定で生体認証機能を有効にしてください。</string>
|
||||
<string name="biometric_unavailable_warning">スマートフォンの生体認証が無効になっているため、アプリにウォレットを保存できません。ウォレットを保存するには、スマートフォンの設定で生体認証機能を有効にしてください。</string>
|
||||
<string name="biometric_updated_warning_description">デバイスの生体認証が更新されました。再び生体認証ログインを有効にするため、ウォレットを選び、アクセスコードを入力してください。</string>
|
||||
<string name="biometric_updated_warning_title">対応が必要です</string>
|
||||
<string name="bitcoin_promo_activation_error">プロモーションコードの処理中にエラーが発生しました。しばらくしてからもう一度お試しください。</string>
|
||||
|
|
@ -217,7 +217,7 @@
|
|||
<string name="common_allow">許可する</string>
|
||||
<string name="common_amount">金額</string>
|
||||
<string name="common_analytics">アナリティクス</string>
|
||||
<string name="common_and">そして</string>
|
||||
<string name="common_and">と</string>
|
||||
<string name="common_apply">適用する</string>
|
||||
<string name="common_approval">承認</string>
|
||||
<string name="common_approve">承認</string>
|
||||
|
|
@ -245,6 +245,7 @@
|
|||
<string name="common_coming_soon">近日公開</string>
|
||||
<string name="common_confirm">確認</string>
|
||||
<string name="common_connecting">接続中</string>
|
||||
<string name="common_contact_support">サポートへのお問い合わせ</string>
|
||||
<string name="common_contact_tangem_support">Tangemサポートへ問い合わせる</string>
|
||||
<string name="common_contact_visa_support">Visaサポートへ問い合わせる</string>
|
||||
<string name="common_continue">続ける</string>
|
||||
|
|
@ -269,7 +270,7 @@
|
|||
<string name="common_enable">有効にする</string>
|
||||
<string name="common_enabled">有効</string>
|
||||
<string name="common_error">エラー</string>
|
||||
<string name="common_estimated_fee">ネットワーク手数料</string>
|
||||
<string name="common_estimated_fee">入金時のネットワーク手数料</string>
|
||||
<string name="common_exchange">スワップ</string>
|
||||
<string name="common_explore">移動する</string>
|
||||
<string name="common_explore_transaction_history">取引履歴を調べる</string>
|
||||
|
|
@ -366,6 +367,7 @@
|
|||
<string name="common_terms_and_conditions">利用規約</string>
|
||||
<string name="common_terms_of_use">利用規約</string>
|
||||
<string name="common_to">宛先</string>
|
||||
<string name="common_to_wallet_name">%sへ</string>
|
||||
<string name="common_today">今日</string>
|
||||
<plurals name="common_tokens_count">
|
||||
<item quantity="other">%d トークン</item>
|
||||
|
|
@ -418,6 +420,7 @@
|
|||
<string name="custom_token_validation_error_not_found_title">トークンは誰でも作成できることに注意してください。</string>
|
||||
<string name="details_buy_wallet">Tangemウォレットを購入</string>
|
||||
<string name="details_chat">チャット</string>
|
||||
<string name="details_get_visa">Tangem Visaを入手</string>
|
||||
<string name="details_manage_security_access_code">アクセスコード</string>
|
||||
<string name="details_manage_security_access_code_description">カードをスキャンする前に、正しいアクセスコードを送信する必要があります。</string>
|
||||
<string name="details_manage_security_long_tap">長くタップ</string>
|
||||
|
|
@ -429,7 +432,6 @@
|
|||
<string name="details_row_description_flip_to_hide">デバイスの画面を下に向けると、残高をすばやく非表示にしたり表示したりできます。</string>
|
||||
<string name="details_row_subtitle_signed_hashes_format">%sハッシュ</string>
|
||||
<string name="details_row_title_cid">デバイスID</string>
|
||||
<string name="details_row_title_contact_to_support">サポートへのお問い合わせ</string>
|
||||
<string name="details_row_title_contact_to_support_chat">サポートチャットを開く</string>
|
||||
<string name="details_row_title_create_backup">他のカードをリンクする</string>
|
||||
<string name="details_row_title_currency">アプリ通貨</string>
|
||||
|
|
@ -518,7 +520,7 @@
|
|||
<string name="express_status_buying">%sを買い付けています</string>
|
||||
<string name="express_status_buying_active">%sを買い付けています...</string>
|
||||
<string name="express_status_hide_button_text">この取引を非表示にする</string>
|
||||
<string name="express_status_hide_dialog_text">一度非表示にすると、取引状況を再度表示することはできません。代わりに、スワイプして閉じることができます。</string>
|
||||
<string name="express_status_hide_dialog_text">この取引を非表示にすると、ステータス画面には表示されなくなります。ステータス画面を閉じて後で戻りたい場合は、画面をスワイプして閉じてください。</string>
|
||||
<string name="express_status_hide_dialog_title">取引状況を非表示にしますか?</string>
|
||||
<string name="express_swap_not_supported_text">このトークンはサポートされていません。別のトークンを選択してスワップしてください。</string>
|
||||
<string name="express_swap_not_supported_title">%sはサポートされていません</string>
|
||||
|
|
@ -590,7 +592,7 @@
|
|||
<string name="hw_backup_need_finish_first">まずバックアップを完了する</string>
|
||||
<string name="hw_backup_need_title">まずバックアップを完了する</string>
|
||||
<string name="hw_backup_section_other_title">その他の方法</string>
|
||||
<string name="hw_backup_seed_description">秘密鍵をオフラインで安全に保存する物理デバイス。</string>
|
||||
<string name="hw_backup_seed_description">リカバリーフレーズは、ご自身で安全な場所に保管し、資金を守るために他人には絶対に共有しないでください。</string>
|
||||
<string name="hw_backup_seed_title">リカバリーフレーズ</string>
|
||||
<string name="hw_backup_to_secure_description">アクセスコードを使用してウォレットを保護するには、まずバックアップを完了してください。</string>
|
||||
<string name="hw_backup_to_upgrade_description">ウォレットをハードウェアにアップグレードするには、まずバックアップしてください。</string>
|
||||
|
|
@ -684,11 +686,13 @@
|
|||
<string name="markets_apy_placeholder">APY %s</string>
|
||||
<string name="markets_common_my_portfolio">私のポートフォリオ</string>
|
||||
<string name="markets_common_title">マーケット</string>
|
||||
<string name="markets_earn_common_title">Tangemで稼ぐ</string>
|
||||
<string name="markets_generate_addresses_notification">選択したネットワークのアドレスを生成するには、Tangemウォレットカードまたはリングをスキャンする必要があります。</string>
|
||||
<string name="markets_hint">トークンを追加するには、これをスワイプするか、検索バーをタップしてください。</string>
|
||||
<string name="markets_insights_info_description_message">このセクションのデータは、次のネットワークから取得されています: %s</string>
|
||||
<string name="markets_loading_error_title">データを読み込めません…</string>
|
||||
<string name="markets_loading_no_data_title">データなし</string>
|
||||
<string name="markets_pulse_common_title">マーケット動向</string>
|
||||
<string name="markets_quick_actions">クイックアクション</string>
|
||||
<string name="markets_search_header_title">マーケットから探す</string>
|
||||
<string name="markets_search_result_title">結果</string>
|
||||
|
|
@ -777,11 +781,17 @@
|
|||
<string name="markets_token_details_volume">取引量</string>
|
||||
<string name="markets_tooltip_message">これをドラッグするか、検索窓をタップして、マーケットから直接トークンを追加します</string>
|
||||
<string name="markets_tooltip_title">トークンを追加</string>
|
||||
<string name="markets_yield_supply_banner_description">資産を即時アクセス可能な状態に保ったまま、パワーアップさせよう。%s</string>
|
||||
<string name="markets_yield_supply_banner_description">資産を常時アクセス可能な状態に保ったまま、パワーアップさせよう。%s</string>
|
||||
<string name="markets_yield_supply_banner_title">利息モードを有効にする</string>
|
||||
<string name="mobile_wallet_requires_min_os_warning_body">モバイルウォレットを作成するには、%1$sにアップデートする必要があります</string>
|
||||
<string name="mobile_wallet_requires_min_os_warning_title">モバイルウォレットを使用するには、%1$s以降が必要です</string>
|
||||
<string name="news_all_news">すべてのニュース</string>
|
||||
<plurals name="news_published_hours_ago">
|
||||
<item quantity="other">%d時間前</item>
|
||||
</plurals>
|
||||
<plurals name="news_published_minutes_ago">
|
||||
<item quantity="other">%d分前</item>
|
||||
</plurals>
|
||||
<string name="news_stay_in_the_loop">最新情報を入手</string>
|
||||
<string name="nfc_error_unavailable">お使いのデバイスではNFCが使用できません</string>
|
||||
<string name="nft_about_title">NFTについて</string>
|
||||
|
|
@ -837,6 +847,9 @@
|
|||
<string name="no_trustline_xlm_asset">送信先アカウントには、送金されるアセットのトラストラインがありません。</string>
|
||||
<string name="notification_black_friday_text">ウォレットごとに$10相当のBTCをプレゼント\nお早めに!</string>
|
||||
<string name="notification_black_friday_title">ブラックフライデー:最大30% オフ</string>
|
||||
<string name="notification_one_plus_one_button">今すぐチェック</string>
|
||||
<string name="notification_one_plus_one_text">理想のTangemセットを揃えよう。期間限定。</string>
|
||||
<string name="notification_one_plus_one_title">1+1:1つ購入で、2つ目が50%オフ</string>
|
||||
<string name="notification_referral_promo_button">今すぐ参加</string>
|
||||
<string name="notification_referral_promo_text">コードを共有すると、販売ごとに5 USDTを獲得できます。お友達は10%割引になります。</string>
|
||||
<string name="notification_referral_promo_title">友達への紹介で報酬を獲得しよう!</string>
|
||||
|
|
@ -849,7 +862,7 @@
|
|||
<string name="onboarding_access_code_feature_1_title">保護する</string>
|
||||
<string name="onboarding_access_code_feature_2_description">後で各カードおよびリングに個別のアクセスコードを設定できます。</string>
|
||||
<string name="onboarding_access_code_feature_2_title">パーソナライズする</string>
|
||||
<string name="onboarding_access_code_feature_3_description">アクセスコードは、リンクされたカードおよびリング1つで復元できます。すべてのデバイスを1か所に保管しないでください。</string>
|
||||
<string name="onboarding_access_code_feature_3_description">リンクされたカードまたはリングを使って、アクセスコードを復元できます。すべてのデバイスを同じ場所に保管しないでください。</string>
|
||||
<string name="onboarding_access_code_feature_3_title">復元する</string>
|
||||
<string name="onboarding_access_code_hint">アクセスコードとして任意の単語、フレーズ、または数字を選択してください</string>
|
||||
<string name="onboarding_access_code_intro_title">アクセスコードの作成</string>
|
||||
|
|
@ -1193,6 +1206,8 @@
|
|||
<string name="staking_account_initialization_footer">ネットワーク手数料とは、ブロックチェーン上で取引を処理し、承認するために支払う少額の料金です。</string>
|
||||
<string name="staking_account_initialization_message">ステーキングを始めるには、1 TONを取引してTONアカウントを有効化する必要があります。資金はウォレット内にそのまま残ります。これは、ステーキング有効化のためのステップにすぎません。</string>
|
||||
<string name="staking_account_initialization_title">アカウントの有効化</string>
|
||||
<string name="staking_alert_network_fee_updated_message">ネットワーク手数料が変更されました。続行する前に新しい金額をご確認ください。</string>
|
||||
<string name="staking_alert_network_fee_updated_title">ネットワーク手数料が更新されました</string>
|
||||
<string name="staking_amount_requirement_error">ステーキング金額は %s 以上である必要があります</string>
|
||||
<string name="staking_amount_tron_integer_error">ネットワークルールにより、ステーキング金額は%1$s TRX に切り上げられます。</string>
|
||||
<string name="staking_amount_tron_integer_error_unstaking">ネットワークルールにより、ステーキング解除の量は%1$s TRX に切り上げられます。</string>
|
||||
|
|
@ -1230,6 +1245,7 @@
|
|||
<string name="staking_give_permission_fee_footer">ネットワークは、ステーキングのためにトークンの使用を承認していることを確認するために、トークン承認手数料を請求します。</string>
|
||||
<string name="staking_legal">ステーキング機能を使用すると、プロバイダーの%1$sと%2$sに同意したことになります</string>
|
||||
<string name="staking_locked">ロック中</string>
|
||||
<string name="staking_max_amount_requirement_error">最大金額:%s</string>
|
||||
<string name="staking_migrate">移行</string>
|
||||
<string name="staking_native">ネイティブステーキング</string>
|
||||
<string name="staking_no_validators_error_message">現在、ステーキングに使用できるアクティブなバリデータは見つかりません。しばらくしてからもう一度お試しください。</string>
|
||||
|
|
@ -1366,6 +1382,8 @@
|
|||
<string name="swapping_to_title">受け取る</string>
|
||||
<string name="swapping_token_list_title">トークンを選択</string>
|
||||
<string name="swapping_token_not_available">利用不可</string>
|
||||
<string name="tangem_pay_beta_notification_subtitle">皆様からのフィードバックをお待ちしております</string>
|
||||
<string name="tangem_pay_beta_notification_title">Tangem Payのベータ版を公開しました</string>
|
||||
<string name="tangem_pay_card_frozen">カードが凍結されています</string>
|
||||
<string name="tangem_pay_card_payment">カード決済</string>
|
||||
<string name="tangem_pay_deposit">入金</string>
|
||||
|
|
@ -1379,6 +1397,7 @@
|
|||
<string name="tangem_pay_freeze_card_freeze">一時停止</string>
|
||||
<string name="tangem_pay_freeze_card_success">カードが凍結されています</string>
|
||||
<string name="tangem_pay_get_help">サポートを受ける</string>
|
||||
<string name="tangem_pay_other">その他</string>
|
||||
<string name="tangem_pay_status_completed">完了</string>
|
||||
<string name="tangem_pay_status_declined">拒否</string>
|
||||
<string name="tangem_pay_status_pending">保留中</string>
|
||||
|
|
@ -1430,9 +1449,14 @@
|
|||
<string name="tangempay_card_details_withdraw_error_title">現在、出金ができません</string>
|
||||
<string name="tangempay_card_details_withdraw_in_progress_description">現在の処理が完了するまでは、スワップや新しい出金を開始することはできません。</string>
|
||||
<string name="tangempay_card_details_withdraw_in_progress_title">出金処理中です</string>
|
||||
<string name="tangempay_change_pin_code">PINコードを変更</string>
|
||||
<string name="tangempay_come_back_if_forget_pin">忘れた場合はアプリに戻って確認できます。</string>
|
||||
<string name="tangempay_failed_to_issue_card">カードの発行に失敗しました</string>
|
||||
<string name="tangempay_failed_to_issue_card_retry_description">技術的なエラーが発生しました。下のボタンをクリックして、もう一度お試しください。</string>
|
||||
<string name="tangempay_failed_to_issue_card_support_description">技術的なエラーが発生しました。サポートへお問い合わせください。</string>
|
||||
<string name="tangempay_get_banner_description">暗号資産を日常の支払いに使おう。\n\nこれまでにないタイプの決済カード。</string>
|
||||
<string name="tangempay_get_tangem_pay">Tangem Payを入手</string>
|
||||
<string name="tangempay_go_to_support">サポートへ移動</string>
|
||||
<string name="tangempay_issue_card_notification_description">通常は最大で15分ほどかかります</string>
|
||||
<string name="tangempay_issue_card_notification_title">Tangemカードのセットアップ</string>
|
||||
<string name="tangempay_issuing_your_card">カードを発行しています</string>
|
||||
|
|
@ -1440,8 +1464,11 @@
|
|||
<string name="tangempay_kyc_card_ready_notification_title">Tangem Pay</string>
|
||||
<string name="tangempay_kyc_failed_description">プロフィールを確認できませんでした。ご不明な点があればサポートまでお問い合わせください。</string>
|
||||
<string name="tangempay_kyc_failed_title">申し訳ございませんが、本人確認を行うことができませんでした</string>
|
||||
<string name="tangempay_kyc_in_progress">KYC進行中</string>
|
||||
<string name="tangempay_kyc_in_progress_notification_button">ステータスを表示</string>
|
||||
<string name="tangempay_kyc_in_progress_notification_title">Tangem PayのKYC手続き進行中</string>
|
||||
<string name="tangempay_onboarding_banner_description">暗号資産を、リアルな支払いに。\n他とはまったく違う、新しいタイプの決済カード。</string>
|
||||
<string name="tangempay_onboarding_banner_title">Tangem Visaカード</string>
|
||||
<string name="tangempay_onboarding_get_card_button_text">カードをGET</string>
|
||||
<string name="tangempay_onboarding_pay_description">Apple PayとGoogle Payに対応したデジタルカード付き</string>
|
||||
<string name="tangempay_onboarding_pay_title">どこでも暗号資産を使える</string>
|
||||
|
|
@ -1455,9 +1482,12 @@
|
|||
<string name="tangempay_service_unavailable_description">技術的な問題を修正しています。後でもう一度お試しください。</string>
|
||||
<string name="tangempay_service_unavailable_title">サービスは一時的に利用できません</string>
|
||||
<string name="tangempay_service_unreachable_try_later">現在サービスに接続できません。後ほどもう一度お試しください。</string>
|
||||
<string name="tangempay_sync_needed">同期が必要です</string>
|
||||
<string name="tangempay_tangem_visa_card">Tangem Visaカード</string>
|
||||
<string name="tangempay_temporarily_unavailable">Tangem Payは一時的に利用できません</string>
|
||||
<string name="tangempay_title">Tangem Pay</string>
|
||||
<string name="tangempay_use_tangem_device_to_restore_payment_account">カードまたはリングを使用して、支払いアカウントへのアクセスを復元してください。</string>
|
||||
<string name="tangempay_your_pin_code">PINコード</string>
|
||||
<string name="this_is_my_wallet_title">これは私のウォレットです</string>
|
||||
<string name="toast_balances_hidden">残高非表示</string>
|
||||
<string name="toast_balances_shown">残高表示</string>
|
||||
|
|
@ -1501,6 +1531,7 @@
|
|||
<string name="transaction_history_multiple_addresses">複数のアドレス</string>
|
||||
<string name="transaction_history_not_supported_description">現在、このブロックチェーンでは取引履歴はサポートされていません。しかしご心配なく!弊社で対応中です。その間、エクスプローラーで確認することができます。</string>
|
||||
<string name="transaction_history_operation">オペレーション</string>
|
||||
<string name="transaction_history_transaction_for_address">対象:%s</string>
|
||||
<string name="transaction_history_transaction_from_address">送金元: %s</string>
|
||||
<string name="transaction_history_transaction_to_address">送金先: %s</string>
|
||||
<string name="transaction_history_transaction_validator">バリデーター: %s</string>
|
||||
|
|
@ -1551,6 +1582,7 @@
|
|||
<item quantity="other">%d日間利用可能</item>
|
||||
</plurals>
|
||||
<string name="visa_main_balances_and_limits">残高と限度額</string>
|
||||
<string name="visa_onboarding_access_code_description">アクセスコードは、支払いアカウントの管理および不正アクセスからの保護に使用されます。</string>
|
||||
<string name="visa_onboarding_access_code_navigation_title">アクセスコード</string>
|
||||
<string name="visa_onboarding_close_alert_message">本当に終了してもよろしいですか?中断したところから後で続行できます。</string>
|
||||
<string name="visa_onboarding_in_progress_description">長くはかかりません。アカウントを設定しています。</string>
|
||||
|
|
@ -1847,7 +1879,7 @@
|
|||
<string name="welcome_create_wallet_feature_one_tap">ワンタップで開始</string>
|
||||
<string name="welcome_create_wallet_feature_seamless">シームレスで安全</string>
|
||||
<string name="welcome_create_wallet_feature_use">シンプルな操作</string>
|
||||
<string name="welcome_create_wallet_hardware_description">Tangemでハードウェアウォレットを作成しましょう。銀行のカードのようにスリムで、金庫のように安全です。</string>
|
||||
<string name="welcome_create_wallet_hardware_description">Tangemでハードウェアウォレットを作成しよう。キャッシュカードのようにスリムで、金庫のように安全。</string>
|
||||
<string name="welcome_create_wallet_mobile_description">ソフトウェアウォレットを作成またはインポート</string>
|
||||
<string name="welcome_create_wallet_mobile_description_full">スマートフォン上にソフトウェアウォレットを作成またはインポートする。</string>
|
||||
<string name="welcome_create_wallet_mobile_title">モバイルウォレットから始める</string>
|
||||
|
|
@ -1904,6 +1936,8 @@
|
|||
<string name="yield_module_fee_policy_sheet_title">入金手数料ポリシー</string>
|
||||
<string name="yield_module_fee_policy_tangem_service_fee_title">Tangemは、生成された利息に対して15%サービス手数料も徴収します。</string>
|
||||
<string name="yield_module_high_fee_error">ネットワーク手数料が下がるか、残高が最低必要額に達すると、資金は自動的にAaveに供給されます。</string>
|
||||
<string name="yield_module_high_network_fees_notification_description">市場が非常に活発なため、現在の手数料は通常よりも高くなっています。今すぐ続行するか、手数料が下がるのを待って後で再確認することもできます。</string>
|
||||
<string name="yield_module_high_network_fees_notification_title">ネットワーク手数料が高額です</string>
|
||||
<string name="yield_module_historical_returns">過去のリターン</string>
|
||||
<string name="yield_module_main_screen_promo_banner_message">保有資産に年利%1$s%%を適用</string>
|
||||
<string name="yield_module_main_view_approve_notification_description">利息モードでのトークンの承認が取り消されました。トークンを開いて再度許可してください。</string>
|
||||
|
|
@ -1920,7 +1954,7 @@
|
|||
<string name="yield_module_promo_screen_self_custodial_title">分散型・自己管理型</string>
|
||||
<string name="yield_module_promo_screen_terms_disclaimer">このサービスを利用することにより、プロバイダー\n%1$sおよび%2$sに同意するものとします。</string>
|
||||
<string name="yield_module_promo_screen_title">Aaveに接続</string>
|
||||
<string name="yield_module_promo_screen_title_v2">残高に %1$s%% の年利(APY)を適用</string>
|
||||
<string name="yield_module_promo_screen_title_v2">保有資産に\n年利%1$s%%を適用</string>
|
||||
<string name="yield_module_promo_screen_variable_rate_info">Aave %1$s%% • 変動金利</string>
|
||||
<string name="yield_module_promo_screen_variable_rate_info_v2">変動金利</string>
|
||||
<string name="yield_module_provider">Aave</string>
|
||||
|
|
@ -1950,12 +1984,12 @@
|
|||
<string name="yield_module_token_details_earn_notification_processing">利息モードの有効化</string>
|
||||
<string name="yield_module_token_details_earn_notification_title">利息モード</string>
|
||||
<string name="yield_module_transaction_deploy_contract">利息モードコントラクトのデプロイ</string>
|
||||
<string name="yield_module_transaction_enter">利息モードを有効にする</string>
|
||||
<string name="yield_module_transaction_enter">利息モードが有効になりました</string>
|
||||
<string name="yield_module_transaction_enter_subtitle">%1$sがAaveに供給されました</string>
|
||||
<string name="yield_module_transaction_exit">利息モードを無効にする</string>
|
||||
<string name="yield_module_transaction_exit">利息モードが無効になりました</string>
|
||||
<string name="yield_module_transaction_exit_subtitle">%1$sがAaveから引き出されました</string>
|
||||
<string name="yield_module_transaction_initialize">利息モードをセットアップ</string>
|
||||
<string name="yield_module_transaction_reactivate">利息モードの再有効化</string>
|
||||
<string name="yield_module_transaction_initialize">利息モードを初期化しました</string>
|
||||
<string name="yield_module_transaction_reactivate">利息モードが再度有効になりました</string>
|
||||
<string name="yield_module_transaction_topup">Aaveへの供給</string>
|
||||
<string name="yield_module_transaction_topup_subtitle">%1$sがAaveに供給されました</string>
|
||||
<string name="yield_module_transaction_withdraw">Aaveから引き出す</string>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,10 @@
|
|||
<string name="access_code_alert_skip_description">Ваш кошелёк не защищён без кода доступа.</string>
|
||||
<string name="access_code_alert_skip_ok">Сбросить все равно</string>
|
||||
<string name="access_code_alert_skip_title">Код доступа не задан</string>
|
||||
<string name="access_code_alert_validation_cancel">Изменить код</string>
|
||||
<string name="access_code_alert_validation_description">Ваш код доступа будет использоваться для разблокировки кошелька и защиты доступа к вашим активам.</string>
|
||||
<string name="access_code_alert_validation_ok">Использовать</string>
|
||||
<string name="access_code_alert_validation_title">Код доступа может быть легко угадан</string>
|
||||
<string name="access_code_check_title">Введите код доступа</string>
|
||||
<string name="access_code_check_warining_delete">Неверный код доступа. Ваш мобильный кошелёк будет удалён после ещё %s неверных попыток.</string>
|
||||
<string name="access_code_confirm_description">Подтвердите ваш код доступа, чтобы продолжить.</string>
|
||||
|
|
@ -14,6 +18,7 @@
|
|||
<string name="account_add_limit_dialog_title">Невозможно добавить новый аккаунт.</string>
|
||||
<string name="account_archived_accounts">Архивированные аккаунты</string>
|
||||
<string name="account_archived_recover">Восстановить</string>
|
||||
<string name="account_archived_recover_dialog_title">Восстановить аккаунт</string>
|
||||
<string name="account_archived_recover_error_message">Лимит в 20 активных аккаунтов достигнут. Пожалуйста, зархивируйте один аккаунт, чтобы продолжить.</string>
|
||||
<string name="account_archived_recover_error_title">Невозможно восстановить аккаунт</string>
|
||||
<string name="account_archived_title">В архиве</string>
|
||||
|
|
@ -36,6 +41,7 @@
|
|||
<string name="account_form_placeholder_new_account">Новый аккаунт</string>
|
||||
<string name="account_form_title_create">Добавить аккаунт</string>
|
||||
<string name="account_form_title_edit">Редактировать аккаунт</string>
|
||||
<string name="account_generic_error_dialog_message">Попробуйте позже. Если проблема повторится, обратитесь в поддержку — мы поможем её решить.</string>
|
||||
<string name="account_label_tokens_info">%1$s в %2$s</string>
|
||||
<string name="account_main_account_title">Основной аккаунт</string>
|
||||
<string name="account_recover_limit_dialog_description">Лимит %1$s активных аккаунтов превышен. Архивируйте один, чтобы продолжить.</string>
|
||||
|
|
@ -113,7 +119,7 @@
|
|||
<string name="backup_complete_description">Вы успешно завершили бэкап вашего кошелька.</string>
|
||||
<string name="backup_complete_seed_description">Эти слова невозможно восстановить, если они будут потеряны. Храните их в надёжном месте.</string>
|
||||
<string name="backup_complete_title">Бэкап завершен</string>
|
||||
<string name="backup_info_description">Ваша секретная фраза восстановления — это фиксированный набор из %s случайных слов для доступа к вашему кошельку и его восстановления.</string>
|
||||
<string name="backup_info_description">Ваша фраза восстановления — фиксированный набор из %s случайных слов для доступа и восстановления кошелька.</string>
|
||||
<string name="backup_info_keep_description">Эти слова невозможно восстановить, если они будут потеряны. Храните их в безопасности.</string>
|
||||
<string name="backup_info_keep_title">Храните в безопасности</string>
|
||||
<string name="backup_info_save_description">Сохраните эти %s слов в безопасном месте и никому их не сообщайте.</string>
|
||||
|
|
@ -129,10 +135,16 @@
|
|||
<string name="balance_hidden_title">Балансы скрыты</string>
|
||||
<string name="beta_mode_warning_message">Согласно информации от разработчиков сети, токены Kaspa находятся в режиме бета. Следите за обновлениями!</string>
|
||||
<string name="beta_mode_warning_title">Бета режим</string>
|
||||
<string name="biometric_disabled_warning_description">Биометрия отключена на вашем устройстве, поэтому вы не можете использовать её для разблокировки кошельков. Включите биометрию в настройках устройства, чтобы снова использовать этот способ.</string>
|
||||
<string name="biometric_disabled_warning_title">Биометрическая аутентификации отключена</string>
|
||||
<string name="biometric_lockout_permanent_warning_description">Пожалуйста, отсканируйте карту или кольцо</string>
|
||||
<string name="biometric_lockout_permanent_warning_description_2">Вы достигли лимита попыток биометрии. Разблокируйте кошелёк с помощью касания устройства или введите код доступа.</string>
|
||||
<string name="biometric_lockout_permanent_warning_title">Биометрическая аутентификации заблокирована</string>
|
||||
<string name="biometric_lockout_warning_description">Пожалуйста, попробуйте снова через 30 секунд или отсканируйте карту или кольцо</string>
|
||||
<string name="biometric_lockout_warning_description_2">Вход по биометрии временно заблокирован. Попробуйте снова через 30 секунд или разблокируйте кошелёк с помощью прикладывания устройства или кода доступа.</string>
|
||||
<string name="biometric_lockout_warning_title">Слишком много попыток</string>
|
||||
<string name="biometric_unavailable_warning">Вы отключили биометрическую аутентификацию на вашем телефоне и не сможете сохранять кошельки в приложении. Для сохранения кошельков, пожалуйста, включите функцию биометрической аутентификации в настройках телефона.</string>
|
||||
<string name="biometric_updated_warning_title">Внимание</string>
|
||||
<string name="bitcoin_promo_activation_error">При обработке промокода произошла ошибка. Пожалуйста, попробуйте позже.</string>
|
||||
<string name="bitcoin_promo_activation_error_title">Ошибка активации</string>
|
||||
<string name="bitcoin_promo_activation_success">Ваш промокод был успешно активирован. Награда будет зачислена на ваш Bitcoin адрес в течение 14 дней.</string>
|
||||
|
|
@ -207,7 +219,7 @@
|
|||
<string name="common_approve">Разрешить</string>
|
||||
<string name="common_attention">Внимание</string>
|
||||
<string name="common_available_networks">Доступные сети</string>
|
||||
<string name="common_backup">Резервное копирование</string>
|
||||
<string name="common_backup">Резервная копия</string>
|
||||
<string name="common_balance">Баланс: %s</string>
|
||||
<string name="common_balance_title">Баланс</string>
|
||||
<string name="common_biometric_authentication">биометрическую аутентификацию</string>
|
||||
|
|
@ -229,6 +241,7 @@
|
|||
<string name="common_coming_soon">Скоро появится</string>
|
||||
<string name="common_confirm">Подтвердить</string>
|
||||
<string name="common_connecting">Подключение</string>
|
||||
<string name="common_contact_support">Обратиться в поддержку</string>
|
||||
<string name="common_continue">Продолжить</string>
|
||||
<string name="common_convert">Конвертировать</string>
|
||||
<string name="common_copy">Копировать</string>
|
||||
|
|
@ -419,7 +432,6 @@
|
|||
<string name="details_row_description_flip_to_hide">Переверните экран вашего устройства вниз, чтобы быстро скрыть и отобразить балансы</string>
|
||||
<string name="details_row_subtitle_signed_hashes_format">%s хэшей</string>
|
||||
<string name="details_row_title_cid">Номер устройства</string>
|
||||
<string name="details_row_title_contact_to_support">Обратиться в поддержку</string>
|
||||
<string name="details_row_title_contact_to_support_chat">Открыть чат поддержки</string>
|
||||
<string name="details_row_title_create_backup">Добавить еще карты</string>
|
||||
<string name="details_row_title_currency">Валюта приложения</string>
|
||||
|
|
@ -576,16 +588,16 @@
|
|||
<string name="hw_backup_need_title">Сначала завершите создание резервной копии</string>
|
||||
<string name="hw_backup_no_backup">Не завершено</string>
|
||||
<string name="hw_backup_section_other_title">Другие способы</string>
|
||||
<string name="hw_backup_seed_description">Физические устройства, которые надёжно хранят ваш приватный ключ офлайн.</string>
|
||||
<string name="hw_backup_seed_description">Сохраните фразу восстановления в безопасном месте и держите её в секрете.</string>
|
||||
<string name="hw_backup_seed_title">Фраза восстановления</string>
|
||||
<string name="hw_backup_to_secure_description">Чтобы защитить ваш кошелёк с помощью кода доступа, сначала завершите резервное копирование.</string>
|
||||
<string name="hw_backup_to_upgrade_description">Чтобы улучшить кошелёк до аппаратного, сначала создайте резервную копию.</string>
|
||||
<string name="hw_create_keys_description">Ваши приватные ключи надёжно зашифрованы и хранятся на вашем телефоне</string>
|
||||
<string name="hw_create_keys_title">Ключи хранятся в приложении</string>
|
||||
<string name="hw_create_seed_description">Создайте или восстановите свой кошелёк с помощью фразы восстановления — вашей встроенной резервной копии</string>
|
||||
<string name="hw_create_seed_title">Резервная копия сид-фразы</string>
|
||||
<string name="hw_create_seed_description">Создайте или импортируйте кошелёк с помощью вашей фразы восстановления.</string>
|
||||
<string name="hw_create_seed_title">Резервная копия</string>
|
||||
<string name="hw_create_title">Создать мобильный кошелек</string>
|
||||
<string name="hw_import_existing_wallet">Импортировать существующий кошелек</string>
|
||||
<string name="hw_import_existing_wallet">Импортировать существующий</string>
|
||||
<string name="hw_import_seed_phrase_already_imported">Эта фраза восстановления уже была импортирована</string>
|
||||
<string name="hw_mobile_wallet">Мобильный кошелек</string>
|
||||
<string name="hw_remove_wallet_action_forget_title">Забыть кошелек</string>
|
||||
|
|
@ -602,7 +614,7 @@
|
|||
<string name="hw_remove_wallet_warning_access">Я понимаю, что если я не создал резервную копию кошелька перед его удалением, я могу потерять к нему доступ.</string>
|
||||
<string name="hw_remove_wallet_warning_device">Я понимаю, что удаление моего кошелька не стирает его — оно просто удаляет его с моего устройства.</string>
|
||||
<string name="hw_upgrade_backup_description">Фраза восстановления больше не нужна — ваша карта или кольцо Tangem становятся вашей надёжной резервной копией.</string>
|
||||
<string name="hw_upgrade_backup_title">Резервное копирование с Tangem</string>
|
||||
<string name="hw_upgrade_backup_title">Резервное копирование</string>
|
||||
<string name="hw_upgrade_error_card_already_has_wallet">Это устройство не может быть использовано для апгрейда, оно уже содержит другой кошелек.</string>
|
||||
<string name="hw_upgrade_error_card_key_import">Выберите другое устройство. Это нельзя использовать для обновления.</string>
|
||||
<string name="hw_upgrade_error_wallet2_card_required">Во время операции произошла ошибка.</string>
|
||||
|
|
@ -680,6 +692,7 @@
|
|||
<string name="markets_insights_info_description_message">Данные раздела получены из следующих сетей: %s</string>
|
||||
<string name="markets_loading_error_title">Невозможно загрузить данные</string>
|
||||
<string name="markets_loading_no_data_title">Нет данных</string>
|
||||
<string name="markets_pulse_common_title">Пульс рынка</string>
|
||||
<string name="markets_quick_actions">Быстрые действия</string>
|
||||
<string name="markets_search_header_title">Поиск на рынке</string>
|
||||
<string name="markets_search_result_title">Результат</string>
|
||||
|
|
@ -774,6 +787,10 @@
|
|||
<string name="markets_token_details_volume">Объем</string>
|
||||
<string name="markets_tooltip_message">Потяните вверх или коснитесь поисковой строки, чтобы добавить токены напрямую из рынка</string>
|
||||
<string name="markets_tooltip_title">Добавить токены</string>
|
||||
<string name="markets_yield_supply_banner_description">Увеличивайте доход с активов, сохраняя мгновенный доступ к ним. %s</string>
|
||||
<string name="markets_yield_supply_banner_title">Активировать режим доходности</string>
|
||||
<string name="mobile_wallet_requires_min_os_warning_body">Обновитесь до версии %1$s, чтобы создать мобильный кошелёк</string>
|
||||
<string name="mobile_wallet_requires_min_os_warning_title">Мобильный кошелек требует %1$s или новее.</string>
|
||||
<string name="nfc_error_unavailable">Функция NFC недоступна на вашем устройстве</string>
|
||||
<string name="nft_about_title">О NFT</string>
|
||||
<string name="nft_asset">NFT</string>
|
||||
|
|
@ -834,6 +851,9 @@
|
|||
<string name="no_trustline_xlm_asset">Аккаунт получателя не содержит трастлайна для отправляемого актива.</string>
|
||||
<string name="notification_black_friday_text">Получите $10 в BTC за каждый кошелёк.\nПоторопитесь!</string>
|
||||
<string name="notification_black_friday_title">Чёрная пятница: скидки до 30%</string>
|
||||
<string name="notification_one_plus_one_button">Купить</string>
|
||||
<string name="notification_one_plus_one_text">Время ограничено!</string>
|
||||
<string name="notification_one_plus_one_title">1+1: Купи один кошелёк — получи 50% скидку</string>
|
||||
<string name="notification_referral_promo_button">Присоединиться</string>
|
||||
<string name="notification_referral_promo_text">Поделись промокодом — заработай 5 USDT с каждой покупки. Твои друзья получат скидку 10% на карту Tangem!</string>
|
||||
<string name="notification_referral_promo_title">Получай бонусы за каждого друга!</string>
|
||||
|
|
@ -1379,12 +1399,112 @@
|
|||
<string name="swapping_to_title">Вы получите</string>
|
||||
<string name="swapping_token_list_title">Выберите токен</string>
|
||||
<string name="swapping_token_not_available">не доступен</string>
|
||||
<string name="tangem_pay_deposit">Пополнить</string>
|
||||
<string name="tangem_pay_beta_notification_subtitle">Будем рады вашей обратной связи</string>
|
||||
<string name="tangem_pay_beta_notification_title">Tangem Pay в режиме beta</string>
|
||||
<string name="tangem_pay_card_frozen">Карта заморожена</string>
|
||||
<string name="tangem_pay_card_payment">Оплата картой</string>
|
||||
<string name="tangem_pay_deposit">Пополнение</string>
|
||||
<string name="tangem_pay_dispute">Оспорить</string>
|
||||
<string name="tangem_pay_explore_transaction">Посмотреть в обозревателе</string>
|
||||
<string name="tangem_pay_fee_subtitle">Сервисная комиссия</string>
|
||||
<string name="tangem_pay_fee_title">Комиссия</string>
|
||||
<string name="tangem_pay_get_help">Получить помощь</string>
|
||||
<string name="tangempay_card_details_hide_details">Скрыть детали</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_5">Всё готово! Ваша карта готова к использованию.</string>
|
||||
<string name="tangempay_onboarding_get_card_button_text">Получить карту</string>
|
||||
<string name="tangem_pay_freeze_card_alert_body">Всегда можно разморозить</string>
|
||||
<string name="tangem_pay_freeze_card_alert_title">Заморозить карту?</string>
|
||||
<string name="tangem_pay_freeze_card_failed">Не удалось заморозить карту, попробуйте еще раз</string>
|
||||
<string name="tangem_pay_freeze_card_freeze">Заморозить</string>
|
||||
<string name="tangem_pay_freeze_card_success">Карта заморожена</string>
|
||||
<string name="tangem_pay_get_help">Обратиться в поддержку</string>
|
||||
<string name="tangem_pay_other">Другое</string>
|
||||
<string name="tangem_pay_status_completed">Успешно завершено</string>
|
||||
<string name="tangem_pay_status_declined">Отклонено</string>
|
||||
<string name="tangem_pay_status_pending">В процессе</string>
|
||||
<string name="tangem_pay_terms_fees_limits">Тарифы и полные условия</string>
|
||||
<string name="tangem_pay_terms_limits">Тарифы и лимиты</string>
|
||||
<string name="tangem_pay_transaction_declined_notification_text">Банк отклонил транзакцию</string>
|
||||
<string name="tangem_pay_transaction_fee_notification_text">Эта комиссия покрывает стоимость обработки вашего перевода.</string>
|
||||
<string name="tangem_pay_unfreeze_card_alert_body">Продолжайте пользоваться картой, заморозить всегда успеете</string>
|
||||
<string name="tangem_pay_unfreeze_card_alert_title">Разморозить карту?</string>
|
||||
<string name="tangem_pay_unfreeze_card_failed">Не удалось разморозить карту, попробуйте еще раз</string>
|
||||
<string name="tangem_pay_unfreeze_card_success">Карта разморожена</string>
|
||||
<string name="tangem_pay_withdrawal">Вывод</string>
|
||||
<string name="tangempay_card_details_add_funds">Пополнить</string>
|
||||
<string name="tangempay_card_details_add_funds_subtitle">Способы пополнения</string>
|
||||
<string name="tangempay_card_details_card_number">Номер</string>
|
||||
<string name="tangempay_card_details_change_pin">Сменить ПИН</string>
|
||||
<string name="tangempay_card_details_change_pin_success_description">Карта готова к покупкам</string>
|
||||
<string name="tangempay_card_details_change_pin_success_title">ПИН-код установлен</string>
|
||||
<string name="tangempay_card_details_cvc">CVC</string>
|
||||
<string name="tangempay_card_details_error_text">Не удалось загрузить данные. Повторите попытку позже.</string>
|
||||
<string name="tangempay_card_details_expiry">Срок</string>
|
||||
<string name="tangempay_card_details_freeze_card">Заморозить карту</string>
|
||||
<string name="tangempay_card_details_hide_details">Скрыть</string>
|
||||
<string name="tangempay_card_details_hide_text">Скрыть</string>
|
||||
<string name="tangempay_card_details_open_wallet_button">Открыть Google Wallet</string>
|
||||
<string name="tangempay_card_details_open_wallet_notification_subtitle">Настройте в пару кликов и начините платить</string>
|
||||
<string name="tangempay_card_details_open_wallet_notification_subtitle_apple">Настройте в пару кликов и начините платить</string>
|
||||
<string name="tangempay_card_details_open_wallet_notification_title">Добавьте карту в Google Pay</string>
|
||||
<string name="tangempay_card_details_open_wallet_notification_title_apple">Добавьте карту в Apple Pay</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_1">Откройте Google Wallet</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_1_5_apple">Нажмите на кнопку “+” сверху справа</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_1_apple">Откройте Apple Wallet</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_2">Нажмите \"Добавить карту\"</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_2_apple">Выберите \"Дебетовая или кредитная карта\"</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_3">Заполните данные карты вручную</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_4">Введите код подтверждения, направленный в email или СМС</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_5">Всё готово! Можно пользоваться картой</string>
|
||||
<string name="tangempay_card_details_open_wallet_title">Добавьте карту в Google Pay</string>
|
||||
<string name="tangempay_card_details_open_wallet_title_apple">Добавить карту в Apple Pay</string>
|
||||
<string name="tangempay_card_details_receive_description">Скопируйте свой адрес или покажите QR</string>
|
||||
<string name="tangempay_card_details_receive_error_description">Техническая ошибка. Попробуйте позже или обратитесь в поддержку.</string>
|
||||
<string name="tangempay_card_details_receive_error_title">Пополнение недоступно</string>
|
||||
<string name="tangempay_card_details_reveal_text">Показать</string>
|
||||
<string name="tangempay_card_details_show_details">Реквизиты</string>
|
||||
<string name="tangempay_card_details_swap_description">Пополните карту любым активом через обмен </string>
|
||||
<string name="tangempay_card_details_title">Реквизиты</string>
|
||||
<string name="tangempay_card_details_unfreeze_card">Разморозить карту</string>
|
||||
<string name="tangempay_card_details_withdraw">Вывод</string>
|
||||
<string name="tangempay_card_details_withdraw_error_title">Вывод сейчас недоступен</string>
|
||||
<string name="tangempay_card_details_withdraw_in_progress_description">Вы не можете начать обмен или новый вывод, пока не завершится текущий.</string>
|
||||
<string name="tangempay_card_details_withdraw_in_progress_title">Вывод выполняется</string>
|
||||
<string name="tangempay_change_pin_code">Изменить PIN-код</string>
|
||||
<string name="tangempay_come_back_if_forget_pin">Можно посмотреть здесь, если забудете его.</string>
|
||||
<string name="tangempay_failed_to_issue_card">Не удалось выпустить карту</string>
|
||||
<string name="tangempay_failed_to_issue_card_retry_description">Техническая ошибка, попробуйте ещё раз, нажав кнопку ниже</string>
|
||||
<string name="tangempay_failed_to_issue_card_support_description">Техническая ошибка, свяжитесь с поддержкой</string>
|
||||
<string name="tangempay_get_banner_description">Используйте криптовалюту в реальной жизни. \nКарта, не похожая ни на одну другую.</string>
|
||||
<string name="tangempay_get_tangem_pay">Получить Tangem Pay</string>
|
||||
<string name="tangempay_go_to_support">Написать в поддержку</string>
|
||||
<string name="tangempay_issue_card_notification_description">Обычно это занимает до 15 минут</string>
|
||||
<string name="tangempay_issue_card_notification_title">Готовим вашу Tangem Card</string>
|
||||
<string name="tangempay_issuing_your_card">Выпускаем карту</string>
|
||||
<string name="tangempay_issuing_your_card_description">Выпускаем карту, это займет немного времени.</string>
|
||||
<string name="tangempay_kyc_card_ready_notification_title">Tangem Pay</string>
|
||||
<string name="tangempay_kyc_failed_description">Не удалось подтвердить ваш профиль. Если у вас есть вопросы, обратитесь в службу поддержки.</string>
|
||||
<string name="tangempay_kyc_failed_title">К сожалению, нам не удалось подтвердить вашу личность</string>
|
||||
<string name="tangempay_kyc_in_progress">KYC в процессе</string>
|
||||
<string name="tangempay_kyc_in_progress_notification_button">Посмотреть статус</string>
|
||||
<string name="tangempay_kyc_in_progress_notification_title">KYC в процессе для Tangem Pay</string>
|
||||
<string name="tangempay_onboarding_banner_description">Используйте криптовалюту в реальной жизни. \nКарта, не похожая ни на одну другую.</string>
|
||||
<string name="tangempay_onboarding_banner_title">Tangem Visa Card</string>
|
||||
<string name="tangempay_onboarding_get_card_button_text">Открыть карту</string>
|
||||
<string name="tangempay_onboarding_pay_description">Виртуальную карту можно добавить в Apple Pay и Google Pay</string>
|
||||
<string name="tangempay_onboarding_pay_title">Покупайте где угодно</string>
|
||||
<string name="tangempay_onboarding_purchases_description">Никаких дополнительных комиссий за покупки</string>
|
||||
<string name="tangempay_onboarding_purchases_title">Сколько видишь – столько платишь</string>
|
||||
<string name="tangempay_onboarding_security_description">Мы создадим отдельный платежный счет без раскрытия ваших активов \nи их адресов</string>
|
||||
<string name="tangempay_onboarding_security_title">Абсолютная приватность</string>
|
||||
<string name="tangempay_onboarding_title">Откройте виртуальную \nTangem Pay Card</string>
|
||||
<string name="tangempay_payment_account">Payment account</string>
|
||||
<string name="tangempay_payment_account_sync_needed">Требуется синхронизация платежного счета</string>
|
||||
<string name="tangempay_service_unavailable_description">Мы устраняем техническую проблему. Пожалуйста, попробуйте позже.</string>
|
||||
<string name="tangempay_service_unavailable_title">Сервис временно недоступен</string>
|
||||
<string name="tangempay_service_unreachable_try_later">Сервис временно недоступен. Пожалуйста, попробуйте позже.</string>
|
||||
<string name="tangempay_sync_needed">Требуется синхронизация</string>
|
||||
<string name="tangempay_tangem_visa_card">Tangem Visa Card</string>
|
||||
<string name="tangempay_temporarily_unavailable">Tangem Pay временно недоступен</string>
|
||||
<string name="tangempay_title">Tangem Pay</string>
|
||||
<string name="tangempay_use_tangem_device_to_restore_payment_account">Используйте вашу карту или кольцо для восстановления доступа к платежному счету</string>
|
||||
<string name="tangempay_your_pin_code">Ваш PIN-код</string>
|
||||
<string name="this_is_my_wallet_title">Это мой кошелек</string>
|
||||
<string name="toast_balances_hidden">Балансы скрыты</string>
|
||||
<string name="toast_balances_shown">Балансы показаны</string>
|
||||
|
|
@ -1428,6 +1548,7 @@
|
|||
<string name="transaction_history_multiple_addresses">Несколько адресов</string>
|
||||
<string name="transaction_history_not_supported_description">История транзакций в настоящее время не поддерживается для этого блокчейна. Но не волнуйтесь, мы работаем над этим! А пока вы можете проверить ее в обозревателе.</string>
|
||||
<string name="transaction_history_operation">Операция</string>
|
||||
<string name="transaction_history_transaction_for_address">для: %s</string>
|
||||
<string name="transaction_history_transaction_from_address">от: %s</string>
|
||||
<string name="transaction_history_transaction_to_address">на: %s</string>
|
||||
<string name="transaction_history_transaction_validator">валидатор: %s</string>
|
||||
|
|
@ -1538,6 +1659,7 @@
|
|||
<string name="wallet_import_google_drive_description">Восстановите существующий кошелек через Google Drive.</string>
|
||||
<string name="wallet_import_google_drive_title">Импорт из Google Drive</string>
|
||||
<string name="wallet_import_navtitle">Добавить существующий кошелек</string>
|
||||
<string name="wallet_import_scan_description">Физические устройства, которые безопасно хранят ваш приватный ключ офлайн.</string>
|
||||
<string name="wallet_import_scan_title">Сканировать кошелек Tangem</string>
|
||||
<string name="wallet_import_seed_description">Импортируйте существующий кошелек через вашу фразу восстановления.</string>
|
||||
<string name="wallet_import_seed_navtitle">Имрортировать кошелек</string>
|
||||
|
|
@ -1813,6 +1935,7 @@
|
|||
<string name="yield_module_fee_policy_tangem_service_fee_title">Tangem взимает комиссию за обслуживание в размере 15% от полученного дохода.</string>
|
||||
<string name="yield_module_high_fee_error">Ваши средства будут автоматически переведены в Aave, как только комиссия сети снизится или баланс достигнет минимально необходимой суммы.</string>
|
||||
<string name="yield_module_historical_returns">Историческая доходность</string>
|
||||
<string name="yield_module_main_screen_promo_banner_message">Получай до %1$s APY на свой баланс</string>
|
||||
<string name="yield_module_main_view_approve_notification_description">Разрешение для вашего токена в режиме доходности было отозвано. Откройте токен, чтобы выдать разрешение снова.</string>
|
||||
<string name="yield_module_main_view_approve_notification_title">Необходимо разрешение для токена</string>
|
||||
<string name="yield_module_network_fee_unreachable_notification_description">Проверьте ваше интернет соединение</string>
|
||||
|
|
@ -1827,7 +1950,9 @@
|
|||
<string name="yield_module_promo_screen_self_custodial_title">Децентрализованный и некастодиальный</string>
|
||||
<string name="yield_module_promo_screen_terms_disclaimer">Используя сервис, вы соглашаетесь с %1$s и %2$s</string>
|
||||
<string name="yield_module_promo_screen_title">Подключить Aave</string>
|
||||
<string name="yield_module_promo_screen_title_v2">Подключите %1$s %% APY\nна ваш баланс</string>
|
||||
<string name="yield_module_promo_screen_variable_rate_info">Aave %1$s%% • Плавающая ставка</string>
|
||||
<string name="yield_module_promo_screen_variable_rate_info_v2">Динамическая процентная ставка</string>
|
||||
<string name="yield_module_provider">Aave</string>
|
||||
<string name="yield_module_rate_info_sheet_chart_average">Сред. %s</string>
|
||||
<string name="yield_module_rate_info_sheet_chart_title">Доходность за прошлый год</string>
|
||||
|
|
@ -1854,12 +1979,16 @@
|
|||
<string name="yield_module_token_details_earn_notification_earning_on_your_balance_title">Режим доходности</string>
|
||||
<string name="yield_module_token_details_earn_notification_processing">Включение режима доходности</string>
|
||||
<string name="yield_module_token_details_earn_notification_title">Режим доходности</string>
|
||||
<string name="yield_module_transaction_enter">Включение режима доходности</string>
|
||||
<string name="yield_module_transaction_deploy_contract">Установка контракта режима доходности</string>
|
||||
<string name="yield_module_transaction_enter">Режим доходности подключен</string>
|
||||
<string name="yield_module_transaction_enter_subtitle">%1$s отправлено в Aave</string>
|
||||
<string name="yield_module_transaction_exit">Отключение режима доходности</string>
|
||||
<string name="yield_module_transaction_exit">Режим доходности отключен</string>
|
||||
<string name="yield_module_transaction_exit_subtitle">%1$s выведено из Aave</string>
|
||||
<string name="yield_module_transaction_initialize">Режим доходности инициализирован</string>
|
||||
<string name="yield_module_transaction_reactivate">Режим доходности реактивирован</string>
|
||||
<string name="yield_module_transaction_topup">Перевод средств в Aave</string>
|
||||
<string name="yield_module_transaction_topup_subtitle">%1$s отправлено в Aave</string>
|
||||
<string name="yield_module_transaction_withdraw">Вывод из Aave</string>
|
||||
<string name="yield_module_transfer_mode_automatic">Автоматически</string>
|
||||
<string name="yield_module_unable_to_cover_fee_description">Внесите немного %1$s %2$s, чтобы покрыть комиссию сети за транзакции.</string>
|
||||
<string name="yield_module_unable_to_cover_fee_title">Невозможно покрыть комиссию в %s</string>
|
||||
|
|
|
|||
|
|
@ -133,6 +133,7 @@
|
|||
<string name="common_close">Закрити</string>
|
||||
<string name="common_confirm">Підтвердити</string>
|
||||
<string name="common_connecting">Підключення</string>
|
||||
<string name="common_contact_support">Звернутися у підтримку</string>
|
||||
<string name="common_continue">Продовжити</string>
|
||||
<string name="common_convert">Конвертувати</string>
|
||||
<string name="common_copy">Копіювати</string>
|
||||
|
|
@ -298,7 +299,6 @@
|
|||
<string name="details_row_description_flip_to_hide">Переверніть екран пристрою вниз, щоб швидко приховати та відобразити баланси</string>
|
||||
<string name="details_row_subtitle_signed_hashes_format">%s хешів</string>
|
||||
<string name="details_row_title_cid">Номер пристрою</string>
|
||||
<string name="details_row_title_contact_to_support">Звернутися у підтримку</string>
|
||||
<string name="details_row_title_create_backup">Додати більше карток</string>
|
||||
<string name="details_row_title_currency">Валюта застосунку</string>
|
||||
<string name="details_row_title_flip_to_hide">Приховувати баланси жестом перевороту</string>
|
||||
|
|
@ -1127,6 +1127,22 @@
|
|||
<string name="swapping_to_title">Ви отримаєте</string>
|
||||
<string name="swapping_token_list_title">Оберіть токен</string>
|
||||
<string name="swapping_token_not_available">недоступно</string>
|
||||
<string name="tangempay_card_details_card_number">Номер картки</string>
|
||||
<string name="tangempay_card_details_cvc">CVC</string>
|
||||
<string name="tangempay_card_details_expiry">Термін дії</string>
|
||||
<string name="tangempay_card_details_hide_details">Сховати деталі</string>
|
||||
<string name="tangempay_card_details_open_wallet_notification_title_apple">Додайте свою картку в Apple Pay</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_1_5_apple">Натисніть кнопку \"+\" у верхньому правому куті</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_1_apple">Відкрити Apple Wallet</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_2_apple">Натисніть «Дебетова або кредитна картка»</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_5">Все готово! Ваша картка готова до використання.</string>
|
||||
<string name="tangempay_card_details_open_wallet_title_apple">Додайте свою картку в Apple Pay</string>
|
||||
<string name="tangempay_card_details_show_details">Показати деталі</string>
|
||||
<string name="tangempay_card_details_swap_description">Обміняйте будь-який актив у вашому портфелі на картку</string>
|
||||
<string name="tangempay_card_details_unfreeze_card">Розморозити картку</string>
|
||||
<string name="tangempay_onboarding_banner_title">Tangem Visa Card</string>
|
||||
<string name="tangempay_service_unavailable_description">Ми усуваємо технічну проблему. Будь ласка, спробуйте пізніше.</string>
|
||||
<string name="tangempay_service_unavailable_title">Сервіс тимчасово недоступний</string>
|
||||
<string name="this_is_my_wallet_title">Це мій гаманець</string>
|
||||
<string name="toast_balances_hidden">Баланси приховано</string>
|
||||
<string name="toast_balances_shown">Баланси показано</string>
|
||||
|
|
|
|||
|
|
@ -311,6 +311,111 @@
|
|||
<string name="swapping_swap_action">交易</string>
|
||||
<string name="swapping_token_list_title">選擇代幣</string>
|
||||
<string name="swapping_token_not_available">無法使用</string>
|
||||
<string name="tangem_pay_beta_notification_subtitle">我們期待聆聽您的寶貴意見</string>
|
||||
<string name="tangem_pay_beta_notification_title">Tangem Pay現已開放測試版</string>
|
||||
<string name="tangem_pay_card_frozen">卡片已凍結</string>
|
||||
<string name="tangem_pay_card_payment">信用卡支付</string>
|
||||
<string name="tangem_pay_deposit">充值</string>
|
||||
<string name="tangem_pay_dispute">爭議</string>
|
||||
<string name="tangem_pay_explore_transaction">探索交易</string>
|
||||
<string name="tangem_pay_fee_subtitle">服務費</string>
|
||||
<string name="tangem_pay_fee_title">手續費</string>
|
||||
<string name="tangem_pay_freeze_card_alert_body">保護資金安全,隨時可解凍</string>
|
||||
<string name="tangem_pay_freeze_card_alert_title">凍結您的卡片?</string>
|
||||
<string name="tangem_pay_freeze_card_failed">無法凍結卡片。請稍後再試。</string>
|
||||
<string name="tangem_pay_freeze_card_freeze">凍結</string>
|
||||
<string name="tangem_pay_freeze_card_success">您的卡片已凍結。</string>
|
||||
<string name="tangem_pay_get_help">獲取幫助</string>
|
||||
<string name="tangem_pay_other">其他</string>
|
||||
<string name="tangem_pay_status_completed">已完成</string>
|
||||
<string name="tangem_pay_status_declined">已拒絕</string>
|
||||
<string name="tangem_pay_status_pending">處理中</string>
|
||||
<string name="tangem_pay_terms_fees_limits">條款、費用與限制</string>
|
||||
<string name="tangem_pay_terms_limits">條款與限制</string>
|
||||
<string name="tangem_pay_transaction_declined_notification_text">銀行拒絕了此交易請求。</string>
|
||||
<string name="tangem_pay_transaction_fee_notification_text">此費用用於支付處理您轉帳的成本。</string>
|
||||
<string name="tangem_pay_unfreeze_card_alert_body">繼續使用您的資金。您可以隨時凍結。</string>
|
||||
<string name="tangem_pay_unfreeze_card_alert_title">解凍您的卡片?</string>
|
||||
<string name="tangem_pay_unfreeze_card_failed">無法解凍卡片。請稍後再試。</string>
|
||||
<string name="tangem_pay_unfreeze_card_success">您的卡片已解凍。</string>
|
||||
<string name="tangem_pay_withdrawal">提現</string>
|
||||
<string name="tangempay_card_details_add_funds">添加资金</string>
|
||||
<string name="tangempay_card_details_add_funds_subtitle">充值选项</string>
|
||||
<string name="tangempay_card_details_card_number">卡號</string>
|
||||
<string name="tangempay_card_details_change_pin">修改 PIN</string>
|
||||
<string name="tangempay_card_details_change_pin_success_description">卡片已完全准备好进行支付。</string>
|
||||
<string name="tangempay_card_details_change_pin_success_title">PIN 碼已建立</string>
|
||||
<string name="tangempay_card_details_cvc">CVC</string>
|
||||
<string name="tangempay_card_details_error_text">無法載入資料。請稍後再試。</string>
|
||||
<string name="tangempay_card_details_expiry">有效期</string>
|
||||
<string name="tangempay_card_details_freeze_card">冻结卡片</string>
|
||||
<string name="tangempay_card_details_hide_details">隱藏詳情</string>
|
||||
<string name="tangempay_card_details_hide_text">隐藏</string>
|
||||
<string name="tangempay_card_details_open_wallet_button">打開 Google Wallet</string>
|
||||
<string name="tangempay_card_details_open_wallet_notification_subtitle">只需幾次點擊即可設置 Tangem Pay 並開始使用 Google Pay 付款。</string>
|
||||
<string name="tangempay_card_details_open_wallet_notification_subtitle_apple">设置Tangem Pay只需几次点击,即可开始使用Apple Pay支付</string>
|
||||
<string name="tangempay_card_details_open_wallet_notification_title">将您的卡片添加到 Google Pay</string>
|
||||
<string name="tangempay_card_details_open_wallet_notification_title_apple">將卡片添加到 Apple Pay</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_1">打開 Google Wallet</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_1_5_apple">点击右上角的“+”按钮</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_1_apple">打开Apple Wallet</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_2">点击“添加卡片”</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_2_apple">點擊「借記卡或信用卡」</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_3">手動輸入卡片詳情</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_4">使用發送到您設備的 OTP 驗證卡片。</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_5">全部完成!您的卡片已準備就緒。</string>
|
||||
<string name="tangempay_card_details_open_wallet_title">將卡片添加到 Google Pay</string>
|
||||
<string name="tangempay_card_details_open_wallet_title_apple">添加卡片到 Apple Pay</string>
|
||||
<string name="tangempay_card_details_receive_description">分享您的地址或显示二维码</string>
|
||||
<string name="tangempay_card_details_receive_error_title">暫時無法接收</string>
|
||||
<string name="tangempay_card_details_reveal_text">显示</string>
|
||||
<string name="tangempay_card_details_show_details">顯示詳情</string>
|
||||
<string name="tangempay_card_details_swap_description">將您投資組合中的任何資產兌換成卡片</string>
|
||||
<string name="tangempay_card_details_title">卡片详情</string>
|
||||
<string name="tangempay_card_details_unfreeze_card">解凍卡片</string>
|
||||
<string name="tangempay_card_details_withdraw">提现</string>
|
||||
<string name="tangempay_card_details_withdraw_error_title">目前无法提现</string>
|
||||
<string name="tangempay_card_details_withdraw_in_progress_description">在当前操作完成之前,您无法启动兑换或新的提款。</string>
|
||||
<string name="tangempay_card_details_withdraw_in_progress_title">提款进行中</string>
|
||||
<string name="tangempay_change_pin_code">修改PIN码</string>
|
||||
<string name="tangempay_come_back_if_forget_pin">如果忘记了,请返回应用查看。</string>
|
||||
<string name="tangempay_failed_to_issue_card">无法发行卡片</string>
|
||||
<string name="tangempay_failed_to_issue_card_retry_description">出现技术错误,请点击下方按钮重试</string>
|
||||
<string name="tangempay_failed_to_issue_card_support_description">出现技术错误,请联系客服</string>
|
||||
<string name="tangempay_get_banner_description">使用您的加密货币进行真实世界消费。\n这是一张与众不同的支付卡。</string>
|
||||
<string name="tangempay_get_tangem_pay">获取Tangem Pay</string>
|
||||
<string name="tangempay_go_to_support">前往客服中心</string>
|
||||
<string name="tangempay_issue_card_notification_description">通常需要最多15分钟</string>
|
||||
<string name="tangempay_issue_card_notification_title">設置您的 Tangem 卡</string>
|
||||
<string name="tangempay_issuing_your_card">正在发行您的卡片</string>
|
||||
<string name="tangempay_issuing_your_card_description">正在为您准备卡片,这可能需要一些时间</string>
|
||||
<string name="tangempay_kyc_card_ready_notification_title">Tangem Pay</string>
|
||||
<string name="tangempay_kyc_failed_description">我们无法验证您的资料。如有任何疑问,请联系客服。</string>
|
||||
<string name="tangempay_kyc_failed_title">很抱歉,我们无法验证您的身份</string>
|
||||
<string name="tangempay_kyc_in_progress">KYC进行中</string>
|
||||
<string name="tangempay_kyc_in_progress_notification_button">查看状态</string>
|
||||
<string name="tangempay_kyc_in_progress_notification_title">Tangem Pay 的 KYC 正在進行中</string>
|
||||
<string name="tangempay_onboarding_banner_description">使用您的加密货币进行真实世界消费。这是一张与众不同的支付卡。</string>
|
||||
<string name="tangempay_onboarding_banner_title">Tangem Visa Card</string>
|
||||
<string name="tangempay_onboarding_get_card_button_text">获取卡片</string>
|
||||
<string name="tangempay_onboarding_pay_description">使用支援 Apple Pay 和 Google Pay 的數位卡</string>
|
||||
<string name="tangempay_onboarding_pay_title">在任何地方花费您的资产</string>
|
||||
<string name="tangempay_onboarding_purchases_description">購物無額外費用</string>
|
||||
<string name="tangempay_onboarding_purchases_title">所見即所付</string>
|
||||
<string name="tangempay_onboarding_security_description">將創建單獨的支付帳戶,且不會透露您的地址和資產</string>
|
||||
<string name="tangempay_onboarding_security_title">無與倫比的隱私</string>
|
||||
<string name="tangempay_onboarding_title">在幾分鐘內獲得免費的 Tangem Pay 卡</string>
|
||||
<string name="tangempay_payment_account">Payment account</string>
|
||||
<string name="tangempay_payment_account_sync_needed">需要同步支付账户</string>
|
||||
<string name="tangempay_service_unavailable_description">我们正在修复技术问题。请稍后再试。</string>
|
||||
<string name="tangempay_service_unavailable_title">服務暫時無法使用</string>
|
||||
<string name="tangempay_service_unreachable_try_later">服务当前不可用,请稍后再试</string>
|
||||
<string name="tangempay_sync_needed">需要同步</string>
|
||||
<string name="tangempay_tangem_visa_card">Tangem Visa Card</string>
|
||||
<string name="tangempay_temporarily_unavailable">Tangem Pay暂时不可用</string>
|
||||
<string name="tangempay_title">Tangem Pay</string>
|
||||
<string name="tangempay_use_tangem_device_to_restore_payment_account">使用您的卡片或戒指恢复对支付账户的访问</string>
|
||||
<string name="tangempay_your_pin_code">您的PIN码</string>
|
||||
<string name="token_details_hide_alert_hide">隱藏</string>
|
||||
<string name="token_details_hide_alert_message">您即將在主屏幕上隱藏此代幣。您可以隨時通過管理代幣頁面將其添加回來。</string>
|
||||
<string name="token_details_hide_alert_title">隱藏 %s</string>
|
||||
|
|
|
|||
|
|
@ -428,6 +428,7 @@
|
|||
<string name="custom_token_validation_error_not_found_title">Note that tokens can be created by anyone</string>
|
||||
<string name="details_buy_wallet">Buy Tangem Wallet</string>
|
||||
<string name="details_chat">Chat</string>
|
||||
<string name="details_get_visa">Get Tangem Visa</string>
|
||||
<string name="details_manage_security_access_code">Access code</string>
|
||||
<string name="details_manage_security_access_code_description">You will have to submit the correct access code before scanning the card</string>
|
||||
<string name="details_manage_security_long_tap">Long Tap</string>
|
||||
|
|
@ -439,7 +440,6 @@
|
|||
<string name="details_row_description_flip_to_hide">Flip your device screen down to quickly hide and show balances</string>
|
||||
<string name="details_row_subtitle_signed_hashes_format">%s hashes</string>
|
||||
<string name="details_row_title_cid">Device ID</string>
|
||||
<string name="details_row_title_contact_to_support">Contact support</string>
|
||||
<string name="details_row_title_contact_to_support_chat">Open support chat</string>
|
||||
<string name="details_row_title_create_backup">Link More Cards</string>
|
||||
<string name="details_row_title_currency">App Currency</string>
|
||||
|
|
@ -528,7 +528,7 @@
|
|||
<string name="express_status_buying">Buying %s</string>
|
||||
<string name="express_status_buying_active">Buying %s...</string>
|
||||
<string name="express_status_hide_button_text">Hide this transaction</string>
|
||||
<string name="express_status_hide_dialog_text">Once hidden, the transaction status cannot be viewed again. You can simply swipe to dismiss instead.</string>
|
||||
<string name="express_status_hide_dialog_text">If you hide this transaction, it won’t appear in the status screen anymore. If you just want to close the status screen and return later, simply swipe it away instead.</string>
|
||||
<string name="express_status_hide_dialog_title">Hide Transaction Status?</string>
|
||||
<string name="express_swap_not_supported_text">This token is not supported. Please choose a different token to swap.</string>
|
||||
<string name="express_swap_not_supported_title">%s is not supported</string>
|
||||
|
|
@ -601,9 +601,9 @@
|
|||
<string name="hw_backup_need_title">Finalize backup first</string>
|
||||
<string name="hw_backup_no_backup">Incomplete</string>
|
||||
<string name="hw_backup_section_other_title">Other methods</string>
|
||||
<string name="hw_backup_seed_description">Physical devices that securely store your private key offline.</string>
|
||||
<string name="hw_backup_seed_description">Manually save your recovery phrase in a secure place and keep it private to protect your funds.</string>
|
||||
<string name="hw_backup_seed_title">Recovery phrase</string>
|
||||
<string name="hw_backup_to_secure_description">To secure your wallet with a Access Code, complete the backup first.</string>
|
||||
<string name="hw_backup_to_secure_description">To secure your wallet with an Access Code, complete the backup first.</string>
|
||||
<string name="hw_backup_to_upgrade_description">To upgrade your wallet to hardware, back it up first.</string>
|
||||
<string name="hw_create_keys_description">Your private keys are securely encrypted and stored on your phone</string>
|
||||
<string name="hw_create_keys_title">Keys are stored in the app</string>
|
||||
|
|
@ -698,11 +698,13 @@
|
|||
<string name="markets_apy_placeholder">APY %s</string>
|
||||
<string name="markets_common_my_portfolio">My portfolio</string>
|
||||
<string name="markets_common_title">Market</string>
|
||||
<string name="markets_earn_common_title">Earn with Tangem</string>
|
||||
<string name="markets_generate_addresses_notification">To generate addresses for selected networks, you must scan your Tangem Wallet card or ring</string>
|
||||
<string name="markets_hint">To add tokens pull this up or tap the search bar</string>
|
||||
<string name="markets_insights_info_description_message">This section’s data is sourced from the following networks: %s</string>
|
||||
<string name="markets_loading_error_title">Unable to load the data…</string>
|
||||
<string name="markets_loading_no_data_title">No data</string>
|
||||
<string name="markets_pulse_common_title">Market Pulse</string>
|
||||
<string name="markets_quick_actions">Quick actions</string>
|
||||
<string name="markets_search_header_title">Search through the market</string>
|
||||
<string name="markets_search_result_title">Result</string>
|
||||
|
|
@ -798,6 +800,14 @@
|
|||
<string name="mobile_wallet_requires_min_os_warning_body">You must update to %1$s in order to create mobile wallet</string>
|
||||
<string name="mobile_wallet_requires_min_os_warning_title">Mobile Wallet requires %1$s or later</string>
|
||||
<string name="news_all_news">All news</string>
|
||||
<plurals name="news_published_hours_ago">
|
||||
<item quantity="one"></item>
|
||||
<item quantity="other">%dh ago</item>
|
||||
</plurals>
|
||||
<plurals name="news_published_minutes_ago">
|
||||
<item quantity="one">%d minute ago</item>
|
||||
<item quantity="other">%d minutes ago</item>
|
||||
</plurals>
|
||||
<string name="news_stay_in_the_loop">Stay in the loop</string>
|
||||
<string name="nfc_error_unavailable">NFC is not available on your device</string>
|
||||
<string name="nft_about_title">About NFT</string>
|
||||
|
|
@ -855,6 +865,9 @@
|
|||
<string name="no_trustline_xlm_asset">The destination account does not have a trustline for the asset being sent.</string>
|
||||
<string name="notification_black_friday_text">Get $10 in BTC with every wallet\nHurry!</string>
|
||||
<string name="notification_black_friday_title">Black Friday: up to 30% OFF</string>
|
||||
<string name="notification_one_plus_one_button">Let’s go</string>
|
||||
<string name="notification_one_plus_one_text">Limited time!</string>
|
||||
<string name="notification_one_plus_one_title">1+1: Buy One Wallet, Get 50% OFF</string>
|
||||
<string name="notification_referral_promo_button">Join Now</string>
|
||||
<string name="notification_referral_promo_text">Share your code - earn 5 USDT per sale. Your friend gets 10% OFF.</string>
|
||||
<string name="notification_referral_promo_title">Get REWARDS for every friend!</string>
|
||||
|
|
@ -1217,6 +1230,8 @@
|
|||
<string name="staking_account_initialization_footer">A network fee is a small payment required to process and confirm your transaction on the blockchain.</string>
|
||||
<string name="staking_account_initialization_message">To begin staking, your TON account must be activated with a transaction of 1 TON. The funds stay in your account because this step only activates it for staking.</string>
|
||||
<string name="staking_account_initialization_title">Account activation</string>
|
||||
<string name="staking_alert_network_fee_updated_message">The network fee has changed. Please review the new amount before proceeding.</string>
|
||||
<string name="staking_alert_network_fee_updated_title">Network fee updated</string>
|
||||
<string name="staking_amount_requirement_error">The amount to stake must be at least %s</string>
|
||||
<string name="staking_amount_tron_integer_error">Staking amount will be rounded to %1$s TRX due to network rules.</string>
|
||||
<string name="staking_amount_tron_integer_error_unstaking">Unstaking amount will be rounded to %1$s TRX due to network rules.</string>
|
||||
|
|
@ -1255,6 +1270,7 @@
|
|||
<string name="staking_give_permission_fee_footer">The network will charge a token approval fee to verify that you are authorizing the use of your token for the staking.</string>
|
||||
<string name="staking_legal">By using staking functionality, you agree with provider’s %1$s and %2$s</string>
|
||||
<string name="staking_locked">Locked</string>
|
||||
<string name="staking_max_amount_requirement_error">Maximum amount: %s</string>
|
||||
<string name="staking_migrate">Migrate</string>
|
||||
<string name="staking_native">Native staking</string>
|
||||
<string name="staking_no_validators_error_message">No active validators available for staking at the moment. Please try again later.</string>
|
||||
|
|
@ -1400,7 +1416,7 @@
|
|||
<string name="tangem_pay_explore_transaction">Explore transaction</string>
|
||||
<string name="tangem_pay_fee_subtitle">Service fees</string>
|
||||
<string name="tangem_pay_fee_title">Fee</string>
|
||||
<string name="tangem_pay_freeze_card_alert_body">Keep your money safe if your card is lost or stolen. You can unfreeze anytime.</string>
|
||||
<string name="tangem_pay_freeze_card_alert_body">Keep your money safe. You can unfreeze anytime.</string>
|
||||
<string name="tangem_pay_freeze_card_alert_title">Freeze your card?</string>
|
||||
<string name="tangem_pay_freeze_card_failed">Failed to freeze the card. Try again later.</string>
|
||||
<string name="tangem_pay_freeze_card_freeze">Freeze</string>
|
||||
|
|
@ -1435,14 +1451,14 @@
|
|||
<string name="tangempay_card_details_open_wallet_notification_subtitle">Set up Tangem Pay in a few taps and start paying with Google Pay.</string>
|
||||
<string name="tangempay_card_details_open_wallet_notification_subtitle_apple">Set up Tangem Pay in a few taps and start paying with Apple Pay.</string>
|
||||
<string name="tangempay_card_details_open_wallet_notification_title">Add your card to Google Pay</string>
|
||||
<string name="tangempay_card_details_open_wallet_notification_title_apple">Add your card to Apple Pay</string>
|
||||
<string name="tangempay_card_details_open_wallet_notification_title_apple">Add your card to Apple Pay</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_1">Open Google Wallet</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_1_5_apple">Tap “+” button on the top right</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_1_apple">Open Apple Wallet</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_2">Tap “Add a card”</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_2_apple">Tap “Debit or Credit Card”</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_3">Enter the card details manually</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_4">Verify card using the OTP sent to your device.</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_4">Verify card using the OTP sent to your device.</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_5">All set! Your card is ready to use.</string>
|
||||
<string name="tangempay_card_details_open_wallet_title">Add card to Google Pay</string>
|
||||
<string name="tangempay_card_details_open_wallet_title_apple">Add card to Apple Pay</string>
|
||||
|
|
@ -1458,9 +1474,14 @@
|
|||
<string name="tangempay_card_details_withdraw_error_title">Withdraw unavailable now</string>
|
||||
<string name="tangempay_card_details_withdraw_in_progress_description">You can\'t initiate swap or new withdrawal till the current one is finished</string>
|
||||
<string name="tangempay_card_details_withdraw_in_progress_title">Withdrawal in progress</string>
|
||||
<string name="tangempay_change_pin_code">Change PIN-code</string>
|
||||
<string name="tangempay_come_back_if_forget_pin">Come back to the app if you forget it.</string>
|
||||
<string name="tangempay_failed_to_issue_card">Failed to issue card</string>
|
||||
<string name="tangempay_failed_to_issue_card_retry_description">A technical error has occurred, please try again by clicking the button below.</string>
|
||||
<string name="tangempay_failed_to_issue_card_support_description">A technical error has occurred, please contact support.</string>
|
||||
<string name="tangempay_get_banner_description">Use your crypto for real world spending. \nIt\'s a payment card unlike any other.</string>
|
||||
<string name="tangempay_get_tangem_pay">Get Tangem Pay</string>
|
||||
<string name="tangempay_go_to_support">Go to Support</string>
|
||||
<string name="tangempay_issue_card_notification_description">It usually takes up to 15 minutes</string>
|
||||
<string name="tangempay_issue_card_notification_title">Setting up your Tangem Card</string>
|
||||
<string name="tangempay_issuing_your_card">Issuing your card</string>
|
||||
|
|
@ -1471,6 +1492,8 @@
|
|||
<string name="tangempay_kyc_in_progress">KYC in progress</string>
|
||||
<string name="tangempay_kyc_in_progress_notification_button">View Status</string>
|
||||
<string name="tangempay_kyc_in_progress_notification_title">KYC in progress for Tangem Pay</string>
|
||||
<string name="tangempay_onboarding_banner_description">Use your crypto for real world spending. \nIt’s a payment card unlike any other.</string>
|
||||
<string name="tangempay_onboarding_banner_title">Tangem Visa Card</string>
|
||||
<string name="tangempay_onboarding_get_card_button_text">Get card</string>
|
||||
<string name="tangempay_onboarding_pay_description">With digital card that works with Apple Pay and Google Pay</string>
|
||||
<string name="tangempay_onboarding_pay_title">Spend your assets anywhere</string>
|
||||
|
|
@ -1485,9 +1508,11 @@
|
|||
<string name="tangempay_service_unavailable_title">Service temporarily unavailable</string>
|
||||
<string name="tangempay_service_unreachable_try_later">The service is currently unreachable. Please try again later.</string>
|
||||
<string name="tangempay_sync_needed">Sync needed</string>
|
||||
<string name="tangempay_tangem_visa_card">Tangem Visa Card</string>
|
||||
<string name="tangempay_temporarily_unavailable">Tangem Pay is temporarily unavailable</string>
|
||||
<string name="tangempay_title">Tangem Pay</string>
|
||||
<string name="tangempay_use_tangem_device_to_restore_payment_account">Use your card or ring to restore access to your payment account</string>
|
||||
<string name="tangempay_your_pin_code">Your PIN code</string>
|
||||
<string name="this_is_my_wallet_title">This is my wallet</string>
|
||||
<string name="toast_balances_hidden">Balances hidden</string>
|
||||
<string name="toast_balances_shown">Balances shown</string>
|
||||
|
|
@ -1531,6 +1556,7 @@
|
|||
<string name="transaction_history_multiple_addresses">Multiple addresses</string>
|
||||
<string name="transaction_history_not_supported_description">Transaction history is currently not supported for this blockchain. But don\'t worry, we\'re working on it! In the meantime you can check it in the explorer.</string>
|
||||
<string name="transaction_history_operation">Operation</string>
|
||||
<string name="transaction_history_transaction_for_address">for: %s</string>
|
||||
<string name="transaction_history_transaction_from_address">from: %s</string>
|
||||
<string name="transaction_history_transaction_to_address">to: %s</string>
|
||||
<string name="transaction_history_transaction_validator">validator: %s</string>
|
||||
|
|
@ -1983,8 +2009,10 @@
|
|||
<string name="yield_module_fee_policy_sheet_title">Top-up fee policy</string>
|
||||
<string name="yield_module_fee_policy_tangem_service_fee_title">Tangem also takes a 15% service fee on yield generated.</string>
|
||||
<string name="yield_module_high_fee_error">Your funds will be automatically supplied to Aave once network fees are lower or your balance meets the minimum required amount.</string>
|
||||
<string name="yield_module_high_network_fees_notification_description">Fees are higher than usual because the market is very active. You can proceed now or check back later when the fees are lower.</string>
|
||||
<string name="yield_module_high_network_fees_notification_title">High Network Fees</string>
|
||||
<string name="yield_module_historical_returns">Historical returns</string>
|
||||
<string name="yield_module_main_screen_promo_banner_message">"Enable %1$s%% APY on your balance"</string>
|
||||
<string name="yield_module_main_screen_promo_banner_message">Enable %1$s%% APY on your balance</string>
|
||||
<string name="yield_module_main_view_approve_notification_description">Approval for your token in Yield Mode has been revoked. Open the token to grant permission again.</string>
|
||||
<string name="yield_module_main_view_approve_notification_title">Token approval needed</string>
|
||||
<string name="yield_module_network_fee_unreachable_notification_description">Check your network connection</string>
|
||||
|
|
@ -2029,12 +2057,12 @@
|
|||
<string name="yield_module_token_details_earn_notification_processing">Enabling Yield Mode</string>
|
||||
<string name="yield_module_token_details_earn_notification_title">Yield Mode</string>
|
||||
<string name="yield_module_transaction_deploy_contract">Yield Mode contract deploy</string>
|
||||
<string name="yield_module_transaction_enter">Yield Mode enable</string>
|
||||
<string name="yield_module_transaction_enter">Yield Mode enabled</string>
|
||||
<string name="yield_module_transaction_enter_subtitle">%1$s supplied to Aave</string>
|
||||
<string name="yield_module_transaction_exit">Yield Mode disable</string>
|
||||
<string name="yield_module_transaction_exit">Yield Mode disabled</string>
|
||||
<string name="yield_module_transaction_exit_subtitle">%1$s withdrawn from Aave</string>
|
||||
<string name="yield_module_transaction_initialize">Yield Mode initialize</string>
|
||||
<string name="yield_module_transaction_reactivate">Yield Mode reactivate</string>
|
||||
<string name="yield_module_transaction_initialize">Yield Mode initialized</string>
|
||||
<string name="yield_module_transaction_reactivate">Yield Mode reactivated</string>
|
||||
<string name="yield_module_transaction_topup">Supply to Aave</string>
|
||||
<string name="yield_module_transaction_topup_subtitle">%1$s supplied to Aave</string>
|
||||
<string name="yield_module_transaction_withdraw">Withdraw from Aave</string>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.tangem.core.ui.components.token
|
|||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.combinedClickable
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
|
|
@ -18,6 +19,7 @@ import androidx.compose.ui.tooling.preview.Preview
|
|||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
|
||||
import androidx.compose.ui.unit.Constraints
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.components.audits.AuditLabelUM
|
||||
import com.tangem.core.ui.components.currency.icon.CurrencyIcon
|
||||
|
|
@ -28,6 +30,7 @@ import com.tangem.core.ui.components.token.internal.*
|
|||
import com.tangem.core.ui.components.token.state.TokenItemState
|
||||
import com.tangem.core.ui.components.token.state.TokenItemState.FiatAmountState
|
||||
import com.tangem.core.ui.components.token.state.TokenItemState.Subtitle2State
|
||||
import com.tangem.core.ui.components.token.state.TokenItemState.PromoBannerState
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.rememberHapticFeedback
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
|
|
@ -44,7 +47,7 @@ private const val TITLE_MIN_WIDTH_COEFFICIENT = 0.3
|
|||
private const val PRICE_MIN_WIDTH_COEFFICIENT = 0.32
|
||||
|
||||
private enum class LayoutId {
|
||||
ICON, TITLE, FIAT_AMOUNT, CRYPTO_AMOUNT, CRYPTO_PRICE, NON_FIAT_CONTENT
|
||||
ICON, TITLE, FIAT_AMOUNT, CRYPTO_AMOUNT, CRYPTO_PRICE, NON_FIAT_CONTENT, PROMO_BANNER
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -109,6 +112,14 @@ fun TokenItem(
|
|||
.testTag(TokenElementsTestTags.TOKEN_ICON),
|
||||
)
|
||||
|
||||
YieldSupplyPromoBanner(
|
||||
state = state.promoBannerState,
|
||||
modifier = Modifier
|
||||
.layoutId(layoutId = LayoutId.PROMO_BANNER)
|
||||
.testTag(TokenElementsTestTags.TOKEN_YIELD_PROMO_BANNER)
|
||||
.fillMaxWidth(),
|
||||
)
|
||||
|
||||
TokenTitle(
|
||||
state = state.titleState,
|
||||
modifier = Modifier
|
||||
|
|
@ -220,6 +231,13 @@ private fun CustomContainer(state: TokenItemState, modifier: Modifier = Modifier
|
|||
|
||||
val nonFiatContent = measurables.measure(layoutId = LayoutId.NON_FIAT_CONTENT, constraints = constraints)
|
||||
|
||||
val promoBanner = when (state.promoBannerState) {
|
||||
is PromoBannerState.Content -> measurables.measure(
|
||||
layoutId = LayoutId.PROMO_BANNER,
|
||||
constraints = constraints,
|
||||
)
|
||||
else -> null
|
||||
}
|
||||
var firstRowRemainingFreeSpace: Int? = null
|
||||
var secondRowRemainingFreeSpace: Int? = null
|
||||
|
||||
|
|
@ -283,10 +301,18 @@ private fun CustomContainer(state: TokenItemState, modifier: Modifier = Modifier
|
|||
)
|
||||
}
|
||||
|
||||
val promoBannerHeight = promoBanner?.height ?: 0
|
||||
val promoOffset = if (promoBannerHeight > 0) {
|
||||
promoBannerHeight - 8.dp.roundToPx()
|
||||
} else {
|
||||
0
|
||||
}
|
||||
|
||||
val layoutHeight = calculateLayoutHeight(
|
||||
state = state,
|
||||
minLayoutHeight = with(density) { dimens.size68.roundToPx() },
|
||||
layoutPadding = verticalPadding,
|
||||
promoOffset = promoOffset,
|
||||
title = title,
|
||||
fiatAmount = fiatAmount,
|
||||
cryptoAmount = cryptoAmount,
|
||||
|
|
@ -294,16 +320,22 @@ private fun CustomContainer(state: TokenItemState, modifier: Modifier = Modifier
|
|||
)
|
||||
|
||||
layout(width = constraints.maxWidth, height = layoutHeight) {
|
||||
icon.placeRelative(x = 0, y = (layoutHeight - icon.height).div(other = 2))
|
||||
promoBanner?.placeRelative(x = 0, y = 0)
|
||||
|
||||
icon.placeRelative(
|
||||
x = 0,
|
||||
y = promoOffset + (layoutHeight - promoOffset - icon.height)
|
||||
.div(other = 2),
|
||||
)
|
||||
|
||||
title.placeRelative(
|
||||
x = icon.width,
|
||||
y = when (state) {
|
||||
y = promoOffset + when (state) {
|
||||
is TokenItemState.NoAddress,
|
||||
is TokenItemState.Unreachable,
|
||||
-> {
|
||||
if (state.subtitleState == null) {
|
||||
(layoutHeight - title.height).div(other = 2)
|
||||
(layoutHeight - promoOffset - title.height).div(other = 2)
|
||||
} else {
|
||||
verticalPadding
|
||||
}
|
||||
|
|
@ -314,8 +346,8 @@ private fun CustomContainer(state: TokenItemState, modifier: Modifier = Modifier
|
|||
|
||||
fiatAmount?.placeRelative(
|
||||
x = layoutWidth - fiatAmount.width,
|
||||
y = when (state.subtitle2State) {
|
||||
null -> (layoutHeight - fiatAmount.height).div(other = 2)
|
||||
y = promoOffset + when (state.subtitle2State) {
|
||||
null -> (layoutHeight - promoOffset - fiatAmount.height).div(other = 2)
|
||||
else -> verticalPadding
|
||||
},
|
||||
)
|
||||
|
|
@ -335,7 +367,7 @@ private fun CustomContainer(state: TokenItemState, modifier: Modifier = Modifier
|
|||
|
||||
nonFiatContent.placeRelative(
|
||||
x = layoutWidth - nonFiatContent.width,
|
||||
y = (layoutHeight - nonFiatContent.height).div(other = 2),
|
||||
y = promoOffset + (layoutHeight - promoOffset - nonFiatContent.height).div(other = 2),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -443,6 +475,7 @@ private fun calculateLayoutHeight(
|
|||
state: TokenItemState,
|
||||
minLayoutHeight: Int,
|
||||
layoutPadding: Int,
|
||||
promoOffset: Int,
|
||||
title: Placeable,
|
||||
fiatAmount: Placeable?,
|
||||
cryptoAmount: Placeable?,
|
||||
|
|
@ -468,7 +501,7 @@ private fun calculateLayoutHeight(
|
|||
}
|
||||
}
|
||||
|
||||
return max(firstColumnHeight, secondColumnHeight).coerceAtLeast(minLayoutHeight)
|
||||
return (promoOffset + max(firstColumnHeight, secondColumnHeight)).coerceAtLeast(promoOffset + minLayoutHeight)
|
||||
}
|
||||
|
||||
@Preview(widthDp = 360, showBackground = true)
|
||||
|
|
@ -587,6 +620,11 @@ private class TokenItemStateProvider : CollectionPreviewParameterProvider<TokenI
|
|||
),
|
||||
onItemClick = {},
|
||||
onItemLongClick = {},
|
||||
promoBannerState = PromoBannerState.Content(
|
||||
title = TextReference.Str(value = "Trusted"),
|
||||
onPromoBannerClick = {},
|
||||
onCloseClick = {},
|
||||
),
|
||||
),
|
||||
TokenItemState.Loading(
|
||||
id = "Loading#1",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,110 @@
|
|||
package com.tangem.core.ui.components.token.internal
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.material3.ripple
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.components.token.state.TokenItemState.PromoBannerState
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
|
||||
@Composable
|
||||
internal fun YieldSupplyPromoBanner(state: PromoBannerState, modifier: Modifier = Modifier) {
|
||||
when (state) {
|
||||
is PromoBannerState.Content -> YieldSupplyPromoBanner(state = state, modifier = modifier)
|
||||
is PromoBannerState.Empty -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
internal fun YieldSupplyPromoBanner(state: PromoBannerState.Content, modifier: Modifier = Modifier) {
|
||||
val bgColor = TangemTheme.colors.control.unchecked
|
||||
Column(modifier = modifier) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.background(color = bgColor, shape = TangemTheme.shapes.roundedCornersXMedium)
|
||||
.padding(horizontal = 12.dp, vertical = 8.dp)
|
||||
.clickable(onClick = state.onPromoBannerClick)
|
||||
.fillMaxWidth(),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Icon(
|
||||
imageVector = ImageVector.vectorResource(id = R.drawable.ic_analytics_up_24),
|
||||
contentDescription = null,
|
||||
tint = TangemTheme.colors.icon.accent,
|
||||
modifier = Modifier
|
||||
.padding(end = TangemTheme.dimens.spacing8)
|
||||
.size(TangemTheme.dimens.size16),
|
||||
)
|
||||
Text(
|
||||
text = state.title.resolveReference(),
|
||||
style = TangemTheme.typography.caption1,
|
||||
color = TangemTheme.colors.text.secondary,
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.padding(end = TangemTheme.dimens.spacing8),
|
||||
)
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_close_24),
|
||||
contentDescription = null,
|
||||
tint = TangemTheme.colors.text.secondary,
|
||||
modifier = Modifier
|
||||
.size(TangemTheme.dimens.size16)
|
||||
.clickable(
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
indication = ripple(bounded = false),
|
||||
onClick = { state.onCloseClick() },
|
||||
),
|
||||
)
|
||||
}
|
||||
Box(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_rectangle_bottom),
|
||||
contentDescription = null,
|
||||
tint = bgColor,
|
||||
modifier = Modifier
|
||||
.size(width = 12.dp, height = 8.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(widthDp = 360, showBackground = true)
|
||||
@Preview(widthDp = 360, showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
private fun Preview_YieldSupplyPromoBanner() {
|
||||
TangemThemePreview {
|
||||
YieldSupplyPromoBanner(
|
||||
state = PromoBannerState.Content(
|
||||
title = TextReference.Str(value = "Earn up to 5% APY"),
|
||||
onPromoBannerClick = {},
|
||||
onCloseClick = {},
|
||||
),
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -34,6 +34,8 @@ sealed class TokenItemState {
|
|||
*/
|
||||
abstract val subtitle2State: Subtitle2State?
|
||||
|
||||
abstract val promoBannerState: PromoBannerState
|
||||
|
||||
/** Callback which will be called when an item is clicked */
|
||||
abstract val onItemClick: ((TokenItemState) -> Unit)?
|
||||
|
||||
|
|
@ -59,6 +61,7 @@ sealed class TokenItemState {
|
|||
) : TokenItemState() {
|
||||
override val fiatAmountState: FiatAmountState = FiatAmountState.Loading
|
||||
override val subtitle2State: Subtitle2State = Subtitle2State.Loading
|
||||
override val promoBannerState: PromoBannerState = PromoBannerState.Empty
|
||||
override val onItemClick: ((TokenItemState) -> Unit)? = null
|
||||
override val onItemLongClick: ((TokenItemState) -> Unit)? = null
|
||||
override val onApyLabelClick: ((TokenItemState) -> Unit)? = null
|
||||
|
|
@ -75,6 +78,7 @@ sealed class TokenItemState {
|
|||
override val subtitleState: SubtitleState = SubtitleState.Locked
|
||||
override val fiatAmountState: FiatAmountState = FiatAmountState.Locked
|
||||
override val subtitle2State: Subtitle2State = Subtitle2State.Locked
|
||||
override val promoBannerState: PromoBannerState = PromoBannerState.Empty
|
||||
override val onItemClick: ((TokenItemState) -> Unit)? = null
|
||||
override val onItemLongClick: ((TokenItemState) -> Unit)? = null
|
||||
override val onApyLabelClick: ((TokenItemState) -> Unit)? = null
|
||||
|
|
@ -99,6 +103,7 @@ sealed class TokenItemState {
|
|||
override val subtitleState: SubtitleState,
|
||||
override val fiatAmountState: FiatAmountState?,
|
||||
override val subtitle2State: Subtitle2State?,
|
||||
override val promoBannerState: PromoBannerState = PromoBannerState.Empty,
|
||||
override val onItemClick: ((TokenItemState) -> Unit)?,
|
||||
override val onItemLongClick: ((TokenItemState) -> Unit)?,
|
||||
override val onApyLabelClick: ((TokenItemState) -> Unit)? = null,
|
||||
|
|
@ -120,6 +125,7 @@ sealed class TokenItemState {
|
|||
) : TokenItemState() {
|
||||
override val subtitleState: SubtitleState? = null
|
||||
override val fiatAmountState: FiatAmountState? = null
|
||||
override val promoBannerState: PromoBannerState = PromoBannerState.Empty
|
||||
override val onItemClick: ((TokenItemState) -> Unit)? = null
|
||||
override val onItemLongClick: ((TokenItemState) -> Unit)? = null
|
||||
override val onApyLabelClick: ((TokenItemState) -> Unit)? = null
|
||||
|
|
@ -146,6 +152,7 @@ sealed class TokenItemState {
|
|||
) : TokenItemState() {
|
||||
override val fiatAmountState: FiatAmountState? = null
|
||||
override val subtitle2State: Subtitle2State? = null
|
||||
override val promoBannerState: PromoBannerState = PromoBannerState.Empty
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -168,6 +175,7 @@ sealed class TokenItemState {
|
|||
override val subtitle2State: Subtitle2State? = null
|
||||
override val onItemClick: ((TokenItemState) -> Unit)? = null
|
||||
override val onApyLabelClick: ((TokenItemState) -> Unit)? = null
|
||||
override val promoBannerState: PromoBannerState = PromoBannerState.Empty
|
||||
}
|
||||
|
||||
@Immutable
|
||||
|
|
@ -254,4 +262,15 @@ sealed class TokenItemState {
|
|||
|
||||
data object Locked : Subtitle2State()
|
||||
}
|
||||
|
||||
@Immutable
|
||||
sealed class PromoBannerState {
|
||||
data class Content(
|
||||
val title: TextReference,
|
||||
val onPromoBannerClick: () -> Unit,
|
||||
val onCloseClick: () -> Unit,
|
||||
) : PromoBannerState()
|
||||
|
||||
data object Empty : PromoBannerState()
|
||||
}
|
||||
}
|
||||
|
|
@ -19,10 +19,12 @@ import androidx.compose.ui.text.style.TextOverflow
|
|||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.constraintlayout.compose.ChainStyle
|
||||
import androidx.constraintlayout.compose.ConstraintLayout
|
||||
import androidx.constraintlayout.compose.Dimension
|
||||
import androidx.constraintlayout.compose.Visibility
|
||||
import androidx.constraintlayout.compose.atLeast
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.components.CircleShimmer
|
||||
import com.tangem.core.ui.components.RectangleShimmer
|
||||
|
|
@ -94,7 +96,7 @@ fun Transaction(state: TransactionState, isBalanceHidden: Boolean, modifier: Mod
|
|||
bottom.linkTo(subtitleItem.top)
|
||||
start.linkTo(iconItem.end)
|
||||
end.linkTo(amountItem.start)
|
||||
width = Dimension.fillToConstraints
|
||||
width = Dimension.fillToConstraints.atLeast(50.dp)
|
||||
},
|
||||
)
|
||||
|
||||
|
|
@ -122,7 +124,6 @@ fun Transaction(state: TransactionState, isBalanceHidden: Boolean, modifier: Mod
|
|||
visibility = state.isGoneIf { amount.isEmpty() }
|
||||
top.linkTo(parent.top)
|
||||
bottom.linkTo(timestampItem.top)
|
||||
start.linkTo(titleItem.end)
|
||||
end.linkTo(parent.end)
|
||||
width = Dimension.fillToConstraints
|
||||
},
|
||||
|
|
@ -436,7 +437,7 @@ private class TransactionItemStateProvider : CollectionPreviewParameterProvider<
|
|||
),
|
||||
TransactionState.Content(
|
||||
txHash = UUID.randomUUID().toString(),
|
||||
amount = "0.625 USDT",
|
||||
amount = "0.62521313 USDT",
|
||||
time = "€0.50",
|
||||
status = Status.Confirmed,
|
||||
direction = Direction.OUTGOING,
|
||||
|
|
|
|||
|
|
@ -7,4 +7,5 @@ object TokenElementsTestTags {
|
|||
const val TOKEN_FIAT_AMOUNT = "TOKEN_FIAT_AMOUNT"
|
||||
const val TOKEN_CRYPTO_AMOUNT = "TOKEN_CRYPTO_AMOUNT"
|
||||
const val TOKEN_NON_FIAT_BLOCK = "TOKEN_NON_FIAT_BLOCK"
|
||||
const val TOKEN_YIELD_PROMO_BANNER = "TOKEN_YIELD_PROMO_BANNER"
|
||||
}
|
||||
9
core/ui/src/main/res/drawable/ic_connect_24.xml
Normal file
9
core/ui/src/main/res/drawable/ic_connect_24.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M11.799,8.899C12.047,8.469 12.597,8.322 13.028,8.57C14.276,9.291 15.268,10.385 15.863,11.698C16.458,13.011 16.627,14.478 16.345,15.892C16.064,17.306 15.347,18.597 14.295,19.582C13.242,20.567 11.908,21.199 10.478,21.387C9.049,21.575 7.596,21.31 6.325,20.631C5.054,19.951 4.027,18.891 3.389,17.598C2.752,16.305 2.535,14.844 2.77,13.422C3.005,12 3.68,10.686 4.699,9.667C5.05,9.316 5.62,9.316 5.971,9.667C6.323,10.019 6.323,10.588 5.971,10.939C5.218,11.693 4.719,12.664 4.546,13.715C4.372,14.766 4.532,15.845 5.004,16.801C5.475,17.756 6.234,18.541 7.173,19.043C8.113,19.545 9.187,19.741 10.244,19.602C11.3,19.462 12.286,18.996 13.064,18.268C13.842,17.539 14.372,16.585 14.58,15.54C14.788,14.495 14.663,13.411 14.223,12.441C13.783,11.47 13.05,10.662 12.128,10.129C11.697,9.88 11.55,9.33 11.799,8.899ZM13.766,2.615C15.196,2.427 16.648,2.692 17.92,3.371C19.191,4.051 20.218,5.111 20.856,6.404C21.494,7.697 21.71,9.158 21.475,10.58C21.24,12.002 20.566,13.316 19.546,14.335C19.195,14.686 18.625,14.686 18.273,14.335C17.922,13.984 17.922,13.414 18.273,13.063C19.027,12.309 19.525,11.338 19.699,10.287C19.872,9.236 19.712,8.156 19.241,7.2C18.77,6.245 18.011,5.46 17.071,4.958C16.131,4.456 15.058,4.26 14.002,4.399C12.945,4.539 11.959,5.005 11.181,5.733C10.404,6.462 9.874,7.416 9.666,8.461C9.458,9.506 9.582,10.59 10.022,11.561C10.462,12.531 11.194,13.34 12.117,13.873C12.547,14.122 12.695,14.672 12.447,15.103C12.198,15.533 11.648,15.68 11.217,15.432C9.969,14.711 8.977,13.617 8.382,12.304C7.788,10.991 7.619,9.524 7.9,8.11C8.181,6.696 8.899,5.406 9.951,4.42C11.003,3.435 12.337,2.804 13.766,2.615Z"
|
||||
android:fillColor="#1E1E1E"/>
|
||||
</vector>
|
||||
15
core/ui/src/main/res/drawable/ic_disconnect_24.xml
Normal file
15
core/ui/src/main/res/drawable/ic_disconnect_24.xml
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M5.91,11.001C5.191,11.745 4.714,12.691 4.546,13.714C4.372,14.764 4.533,15.844 5.004,16.799C5.475,17.755 6.234,18.539 7.173,19.042C8.113,19.544 9.188,19.739 10.244,19.6C11.3,19.461 12.286,18.994 13.064,18.266C13.083,18.249 13.1,18.229 13.119,18.212L14.392,19.485C14.36,19.517 14.328,19.549 14.295,19.581C13.242,20.566 11.907,21.197 10.478,21.385C9.049,21.573 7.596,21.309 6.325,20.629C5.054,19.95 4.027,18.889 3.389,17.596C2.752,16.303 2.535,14.843 2.77,13.42C3,12.027 3.652,10.738 4.637,9.728L5.91,11.001Z"
|
||||
android:fillColor="#1E1E1E"/>
|
||||
<path
|
||||
android:pathData="M4.164,4.164C4.515,3.812 5.086,3.812 5.437,4.164L19.837,18.564C20.188,18.916 20.188,19.485 19.837,19.837C19.485,20.188 18.916,20.188 18.564,19.837L4.164,5.437C3.812,5.086 3.812,4.515 4.164,4.164Z"
|
||||
android:fillColor="#1E1E1E"/>
|
||||
<path
|
||||
android:pathData="M13.766,2.614C15.195,2.426 16.648,2.69 17.92,3.37C19.191,4.049 20.219,5.11 20.856,6.403C21.493,7.696 21.71,9.157 21.475,10.579C21.24,12.001 20.566,13.314 19.546,14.334C19.526,14.354 19.503,14.373 19.481,14.391L18.215,13.125C18.233,13.103 18.253,13.082 18.273,13.061C19.027,12.308 19.525,11.337 19.699,10.286C19.872,9.235 19.712,8.154 19.241,7.199C18.77,6.244 18.01,5.459 17.071,4.957C16.131,4.455 15.058,4.259 14.002,4.398C12.945,4.537 11.959,5.004 11.181,5.732C11.12,5.79 11.059,5.848 11.001,5.909L9.728,4.636C9.801,4.562 9.875,4.49 9.951,4.419C11.003,3.433 12.337,2.802 13.766,2.614Z"
|
||||
android:fillColor="#1E1E1E"/>
|
||||
</vector>
|
||||
14
core/ui/src/main/res/drawable/ic_gear_24.xml
Normal file
14
core/ui/src/main/res/drawable/ic_gear_24.xml
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M12,7.6C14.43,7.6 16.4,9.57 16.4,12C16.4,14.43 14.43,16.4 12,16.4C9.57,16.4 7.6,14.43 7.6,12C7.6,9.57 9.57,7.6 12,7.6ZM12,9.4C10.564,9.4 9.4,10.564 9.4,12C9.4,13.436 10.564,14.6 12,14.6C13.436,14.6 14.6,13.436 14.6,12C14.6,10.564 13.436,9.4 12,9.4Z"
|
||||
android:fillColor="#1E1E1E"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M13.938,2.1C14.721,2.1 15.374,2.099 15.911,2.151C16.468,2.206 16.972,2.324 17.451,2.6C17.931,2.876 18.285,3.252 18.611,3.706C18.926,4.144 19.253,4.708 19.646,5.385L21.569,8.7C21.964,9.38 22.292,9.946 22.517,10.439C22.749,10.949 22.9,11.445 22.9,12C22.9,12.555 22.749,13.051 22.517,13.561C22.292,14.054 21.964,14.62 21.569,15.3L19.646,18.615C19.253,19.292 18.926,19.856 18.611,20.294C18.285,20.748 17.931,21.125 17.451,21.4C16.972,21.676 16.468,21.794 15.911,21.849C15.374,21.901 14.721,21.9 13.938,21.9H10.063C9.279,21.9 8.626,21.901 8.089,21.849C7.532,21.794 7.028,21.676 6.549,21.4C6.069,21.125 5.715,20.748 5.389,20.294C5.074,19.856 4.747,19.292 4.354,18.615L2.431,15.3C2.036,14.62 1.708,14.054 1.483,13.561C1.251,13.051 1.1,12.555 1.1,12C1.1,11.445 1.251,10.949 1.483,10.439C1.708,9.946 2.036,9.38 2.431,8.7L4.354,5.385C4.747,4.708 5.074,4.144 5.389,3.706C5.715,3.252 6.069,2.876 6.549,2.6C7.028,2.324 7.532,2.206 8.089,2.151C8.626,2.099 9.279,2.1 10.063,2.1H13.938ZM10.063,3.9C9.244,3.9 8.694,3.901 8.265,3.943C7.855,3.984 7.628,4.056 7.447,4.16C7.267,4.264 7.089,4.424 6.85,4.757C6.598,5.106 6.321,5.581 5.911,6.288L3.988,9.604C3.576,10.314 3.3,10.79 3.121,11.184C2.95,11.559 2.9,11.792 2.9,12C2.9,12.208 2.95,12.441 3.121,12.816C3.3,13.21 3.576,13.686 3.988,14.396L5.911,17.712C6.321,18.419 6.598,18.894 6.85,19.243C7.089,19.576 7.267,19.736 7.447,19.84C7.628,19.944 7.855,20.016 8.265,20.057C8.694,20.099 9.244,20.1 10.063,20.1H13.938C14.756,20.1 15.306,20.099 15.735,20.057C16.145,20.016 16.372,19.944 16.553,19.84C16.733,19.736 16.911,19.576 17.15,19.243C17.402,18.894 17.678,18.419 18.089,17.712L20.012,14.396C20.424,13.686 20.7,13.21 20.879,12.816C21.05,12.441 21.1,12.208 21.1,12C21.1,11.792 21.05,11.559 20.879,11.184C20.7,10.79 20.424,10.314 20.012,9.604L18.089,6.288C17.678,5.581 17.402,5.106 17.15,4.757C16.911,4.424 16.733,4.264 16.553,4.16C16.372,4.056 16.145,3.984 15.735,3.943C15.306,3.901 14.756,3.9 13.938,3.9H10.063Z"
|
||||
android:fillColor="#1E1E1E"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
||||
9
core/ui/src/main/res/drawable/ic_rectangle_bottom.xml
Normal file
9
core/ui/src/main/res/drawable/ic_rectangle_bottom.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="12dp"
|
||||
android:height="8dp"
|
||||
android:viewportWidth="12"
|
||||
android:viewportHeight="8">
|
||||
<path
|
||||
android:pathData="M0.198,1.178C0.034,0.976 -0.028,0.695 0.012,0.433C0.058,0.135 0.373,0 0.675,0H6.183H11.325C11.627,0 11.943,0.135 11.988,0.433C12.028,0.695 11.966,0.976 11.802,1.178L6.477,7.756C6.214,8.081 5.786,8.081 5.523,7.756L0.198,1.178Z"
|
||||
android:fillColor="#EBEBEB"/>
|
||||
</vector>
|
||||
BIN
core/ui/src/main/res/drawable/img_one_plus_one_promo.webp
Normal file
BIN
core/ui/src/main/res/drawable/img_one_plus_one_promo.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
|
|
@ -69,15 +69,16 @@ fun CoroutineScope.launchOnCancellation(block: suspend () -> Unit) {
|
|||
}
|
||||
|
||||
@Suppress("LongParameterList", "MagicNumber")
|
||||
inline fun <T1, T2, T3, T4, T5, T6, R> combine6(
|
||||
inline fun <T1, T2, T3, T4, T5, T6, T7, R> combine7(
|
||||
flow1: Flow<T1>,
|
||||
flow2: Flow<T2>,
|
||||
flow3: Flow<T3>,
|
||||
flow4: Flow<T4>,
|
||||
flow5: Flow<T5>,
|
||||
flow6: Flow<T6>,
|
||||
crossinline transform: suspend (T1, T2, T3, T4, T5, T6) -> R,
|
||||
): Flow<R> = combine(flow1, flow2, flow3, flow4, flow5, flow6) { arr ->
|
||||
flow7: Flow<T7>,
|
||||
crossinline transform: suspend (T1, T2, T3, T4, T5, T6, T7) -> R,
|
||||
): Flow<R> = combine(flow1, flow2, flow3, flow4, flow5, flow6, flow7) { arr ->
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
transform(
|
||||
arr[0] as T1,
|
||||
|
|
@ -86,5 +87,6 @@ inline fun <T1, T2, T3, T4, T5, T6, R> combine6(
|
|||
arr[3] as T4,
|
||||
arr[4] as T5,
|
||||
arr[5] as T6,
|
||||
arr[6] as T7,
|
||||
)
|
||||
}
|
||||
|
|
@ -61,6 +61,11 @@ internal class DefaultPromoRepository(
|
|||
PromoId.BlackFriday -> {
|
||||
val isActive = getBlackFridayPromoBanner()?.isActive == true
|
||||
|
||||
isActive && shouldShow
|
||||
}
|
||||
PromoId.OnePlusOne -> {
|
||||
val isActive = getOnePlusOnePromoBanner()?.isActive == true
|
||||
|
||||
isActive && shouldShow
|
||||
}
|
||||
}
|
||||
|
|
@ -73,6 +78,7 @@ internal class DefaultPromoRepository(
|
|||
PromoId.Sepa -> flowOf(false)
|
||||
PromoId.VisaPresale -> flowOf(false)
|
||||
PromoId.BlackFriday -> flowOf(false)
|
||||
PromoId.OnePlusOne -> flowOf(false)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -176,11 +182,20 @@ internal class DefaultPromoRepository(
|
|||
}.getOrNull()
|
||||
}
|
||||
|
||||
private suspend fun getOnePlusOnePromoBanner(): PromoBanner? {
|
||||
return runCatching(dispatchers.io) {
|
||||
promoBannerConverter.convert(
|
||||
tangemApi.getPromoBanner(ONE_PLUS_ONE_NAME).getOrThrow(),
|
||||
)
|
||||
}.getOrNull()
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val SEPA_NAME = "sepa"
|
||||
const val VISA_NAME = "visa-waitlist"
|
||||
const val BLACK_FRIDAY_NAME = "black-friday"
|
||||
const val MOONPAY_NAME = "moonpay"
|
||||
const val ONE_PLUS_ONE_NAME = "one-plus-one"
|
||||
const val STORIES_LOAD_DELAY = 1000L
|
||||
}
|
||||
}
|
||||
|
|
@ -2,14 +2,12 @@ package com.tangem.data.pay
|
|||
|
||||
import arrow.core.Either
|
||||
import arrow.core.Either.Companion.catch
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.tangem.blockchain.blockchains.ethereum.Chain
|
||||
import com.tangem.blockchainsdk.utils.ExcludedBlockchains
|
||||
import com.tangem.core.error.UniversalError
|
||||
import com.tangem.data.common.currency.CryptoCurrencyFactory
|
||||
import com.tangem.data.common.network.NetworkFactory
|
||||
import com.tangem.data.pay.util.TangemPayErrorConverter
|
||||
import com.tangem.datasource.di.NetworkMoshi
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.pay.TangemPayCryptoCurrencyFactory
|
||||
|
|
@ -26,8 +24,8 @@ private const val TOKEN_CONTRACT_ADDRESS = "0x3c499c542cef5e3811e1192ce70d8cc03d
|
|||
private const val TOKEN_DECIMALS = 6
|
||||
|
||||
internal class DefaultTangemPayCryptoCurrencyFactory @Inject constructor(
|
||||
@NetworkMoshi moshi: Moshi,
|
||||
excludedBlockchains: ExcludedBlockchains,
|
||||
private val errorConverter: TangemPayErrorConverter,
|
||||
) : TangemPayCryptoCurrencyFactory {
|
||||
|
||||
private val cryptoCurrencyFactory by lazy(mode = LazyThreadSafetyMode.NONE) {
|
||||
|
|
@ -37,8 +35,6 @@ internal class DefaultTangemPayCryptoCurrencyFactory @Inject constructor(
|
|||
NetworkFactory(excludedBlockchains)
|
||||
}
|
||||
|
||||
private val errorConverter by lazy(mode = LazyThreadSafetyMode.NONE) { TangemPayErrorConverter(moshi) }
|
||||
|
||||
override fun create(userWallet: UserWallet, chainId: Int): Either<UniversalError, CryptoCurrency> {
|
||||
return catch {
|
||||
val chain = requireNotNull(Chain.entries.find { it.id == chainId }) { "Can not find chain with $chainId" }
|
||||
|
|
|
|||
|
|
@ -1,8 +1,12 @@
|
|||
package com.tangem.data.pay.repository
|
||||
|
||||
import arrow.core.Either
|
||||
import arrow.core.left
|
||||
import arrow.core.raise.catch
|
||||
import arrow.core.right
|
||||
import com.tangem.core.error.UniversalError
|
||||
import com.tangem.data.pay.util.RainCryptoUtil
|
||||
import com.tangem.data.pay.util.TangemPayErrorConverter
|
||||
import com.tangem.data.visa.config.VisaLibLoader
|
||||
import com.tangem.datasource.api.common.config.ApiConfig
|
||||
import com.tangem.datasource.api.common.config.ApiEnvironment
|
||||
|
|
@ -40,6 +44,7 @@ internal class DefaultTangemPayCardDetailsRepository @Inject constructor(
|
|||
private val rainCryptoUtil: RainCryptoUtil,
|
||||
private val storage: TangemPayStorage,
|
||||
private val cardFrozenStateStore: TangemPayCardFrozenStateStore,
|
||||
private val errorConverter: TangemPayErrorConverter,
|
||||
) : TangemPayCardDetailsRepository {
|
||||
|
||||
private val pollingScope = CoroutineScope(Dispatchers.IO + SupervisorJob())
|
||||
|
|
@ -64,37 +69,39 @@ internal class DefaultTangemPayCardDetailsRepository @Inject constructor(
|
|||
}
|
||||
|
||||
override suspend fun revealCardDetails(userWalletId: UserWalletId): Either<UniversalError, TangemPayCardDetails> {
|
||||
return requestHelper.runWithErrorLogs(TAG) {
|
||||
val publicKeyBase64 = getPublicKeyBase64()
|
||||
val (secretKeyBytes, sessionId) = rainCryptoUtil.generateSecretKeyAndSessionId(publicKeyBase64)
|
||||
return catch(
|
||||
block = {
|
||||
val publicKeyBase64 = getPublicKeyBase64()
|
||||
val (secretKeyBytes, sessionId) = rainCryptoUtil.generateSecretKeyAndSessionId(publicKeyBase64)
|
||||
val result = requestHelper.performRequest(userWalletId = userWalletId) { authHeader ->
|
||||
tangemPayApi.revealCardDetails(
|
||||
authHeader = authHeader,
|
||||
body = CardDetailsRequest(sessionId = sessionId),
|
||||
)
|
||||
}.getOrNull()?.result ?: error("Cannot reveal card details")
|
||||
|
||||
val result = requestHelper.request(userWalletId) { authHeader ->
|
||||
tangemPayApi.revealCardDetails(
|
||||
authHeader = authHeader,
|
||||
body = CardDetailsRequest(sessionId = sessionId),
|
||||
val pan = rainCryptoUtil.decryptSecret(
|
||||
base64Secret = result.pan.secret,
|
||||
base64Iv = result.pan.iv,
|
||||
secretKeyBytes = secretKeyBytes,
|
||||
)
|
||||
}.result ?: error("Cannot reveal card details")
|
||||
|
||||
val pan = rainCryptoUtil.decryptSecret(
|
||||
base64Secret = result.pan.secret,
|
||||
base64Iv = result.pan.iv,
|
||||
secretKeyBytes = secretKeyBytes,
|
||||
)
|
||||
val cvv = rainCryptoUtil.decryptSecret(
|
||||
base64Secret = result.cvv.secret,
|
||||
base64Iv = result.cvv.iv,
|
||||
secretKeyBytes = secretKeyBytes,
|
||||
)
|
||||
secretKeyBytes.fill(0)
|
||||
|
||||
val cvv = rainCryptoUtil.decryptSecret(
|
||||
base64Secret = result.cvv.secret,
|
||||
base64Iv = result.cvv.iv,
|
||||
secretKeyBytes = secretKeyBytes,
|
||||
)
|
||||
secretKeyBytes.fill(0)
|
||||
|
||||
TangemPayCardDetails(
|
||||
pan = pan,
|
||||
cvv = cvv,
|
||||
expirationYear = result.expirationYear,
|
||||
expirationMonth = result.expirationMonth,
|
||||
)
|
||||
}
|
||||
TangemPayCardDetails(
|
||||
pan = pan,
|
||||
cvv = cvv,
|
||||
expirationYear = result.expirationYear,
|
||||
expirationMonth = result.expirationMonth,
|
||||
).right()
|
||||
},
|
||||
catch = { errorConverter.convert(it).left() },
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun setPin(userWalletId: UserWalletId, pin: String): Either<UniversalError, SetPinResult> {
|
||||
|
|
|
|||
|
|
@ -5,14 +5,12 @@ import arrow.core.getOrElse
|
|||
import arrow.core.left
|
||||
import arrow.core.raise.catch
|
||||
import arrow.core.right
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.squareup.wire.Instant
|
||||
import com.tangem.data.pay.util.TangemPayErrorConverter
|
||||
import com.tangem.datasource.api.common.response.ApiResponse
|
||||
import com.tangem.datasource.api.pay.TangemPayAuthApi
|
||||
import com.tangem.datasource.api.pay.models.request.RefreshCustomerWalletAccessTokenRequest
|
||||
import com.tangem.datasource.api.pay.models.response.TangemPayGetTokensResponse
|
||||
import com.tangem.datasource.di.NetworkMoshi
|
||||
import com.tangem.datasource.local.config.environment.EnvironmentConfigStorage
|
||||
import com.tangem.datasource.local.visa.TangemPayStorage
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
|
|
@ -33,7 +31,7 @@ private const val TAG = "TangemPayRequestPerformer"
|
|||
|
||||
@Singleton
|
||||
internal class TangemPayRequestPerformer @Inject constructor(
|
||||
@NetworkMoshi moshi: Moshi,
|
||||
private val errorConverter: TangemPayErrorConverter,
|
||||
private val environmentConfigStorage: EnvironmentConfigStorage,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
private val tangemPayAuthApi: TangemPayAuthApi,
|
||||
|
|
@ -42,7 +40,6 @@ internal class TangemPayRequestPerformer @Inject constructor(
|
|||
|
||||
private val customerWalletAddresses = ConcurrentHashMap<UserWalletId, String>()
|
||||
private val tokensMutex = Mutex()
|
||||
private val errorConverter = TangemPayErrorConverter(moshi)
|
||||
|
||||
@Deprecated("Do not use this method")
|
||||
suspend fun <T : Any> runWithErrorLogs(tag: String, requestBlock: suspend () -> T): Either<VisaApiError, T> {
|
||||
|
|
|
|||
|
|
@ -3,10 +3,16 @@ package com.tangem.data.pay.util
|
|||
import com.squareup.moshi.Moshi
|
||||
import com.tangem.datasource.api.common.response.ApiResponseError
|
||||
import com.tangem.datasource.api.pay.models.response.VisaErrorResponse
|
||||
import com.tangem.datasource.di.NetworkMoshi
|
||||
import com.tangem.domain.visa.error.VisaApiError
|
||||
import com.tangem.utils.converter.Converter
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
class TangemPayErrorConverter(moshi: Moshi) : Converter<Throwable, VisaApiError> {
|
||||
@Singleton
|
||||
internal class TangemPayErrorConverter @Inject constructor(
|
||||
@NetworkMoshi moshi: Moshi,
|
||||
) : Converter<Throwable, VisaApiError> {
|
||||
|
||||
private val visaErrorAdapter by lazy { moshi.adapter(VisaErrorResponse::class.java) }
|
||||
|
||||
|
|
|
|||
|
|
@ -148,14 +148,12 @@ internal object WalletConnectDataModule {
|
|||
@SdkMoshi moshi: Moshi,
|
||||
sessionsManager: WcSessionsManager,
|
||||
factories: WcEthNetwork.Factories,
|
||||
walletManagersFacade: WalletManagersFacade,
|
||||
wcNetworksConverter: WcNetworksConverter,
|
||||
): WcEthNetwork = WcEthNetwork(
|
||||
moshi = moshi,
|
||||
networksConverter = wcNetworksConverter,
|
||||
sessionsManager = sessionsManager,
|
||||
factories = factories,
|
||||
walletManagersFacade = walletManagersFacade,
|
||||
)
|
||||
|
||||
@Provides
|
||||
|
|
@ -165,24 +163,20 @@ internal object WalletConnectDataModule {
|
|||
wcNetworksConverter: WcNetworksConverter,
|
||||
sessionsManager: WcSessionsManager,
|
||||
factories: WcSolanaNetwork.Factories,
|
||||
walletManagersFacade: WalletManagersFacade,
|
||||
): WcSolanaNetwork = WcSolanaNetwork(
|
||||
moshi = moshi,
|
||||
sessionsManager = sessionsManager,
|
||||
factories = factories,
|
||||
networksConverter = wcNetworksConverter,
|
||||
walletManagersFacade = walletManagersFacade,
|
||||
)
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun caipNamespaceDelegate(
|
||||
namespaceConverters: Set<@JvmSuppressWildcards WcNamespaceConverter>,
|
||||
walletManagersFacade: WalletManagersFacade,
|
||||
wcNetworksConverter: WcNetworksConverter,
|
||||
): CaipNamespaceDelegate = CaipNamespaceDelegate(
|
||||
namespaceConverters = namespaceConverters,
|
||||
walletManagersFacade = walletManagersFacade,
|
||||
wcNetworksConverter = wcNetworksConverter,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ import com.tangem.domain.walletconnect.model.*
|
|||
import com.tangem.domain.walletconnect.model.sdkcopy.WcSdkSessionRequest
|
||||
import com.tangem.domain.walletconnect.repository.WcSessionsManager
|
||||
import com.tangem.domain.walletconnect.usecase.method.WcMethodUseCase
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
import jakarta.inject.Inject
|
||||
|
||||
internal class WcEthNetwork(
|
||||
|
|
@ -26,7 +25,6 @@ internal class WcEthNetwork(
|
|||
private val sessionsManager: WcSessionsManager,
|
||||
private val factories: Factories,
|
||||
private val networksConverter: WcNetworksConverter,
|
||||
private val walletManagersFacade: WalletManagersFacade,
|
||||
) : WcRequestToUseCaseConverter {
|
||||
|
||||
override fun toWcMethodName(request: WcSdkSessionRequest): WcEthMethodName? {
|
||||
|
|
@ -57,7 +55,7 @@ internal class WcEthNetwork(
|
|||
is WcEthMethod.SwitchEthereumChain,
|
||||
->
|
||||
anyExistNetwork()
|
||||
?.let { network -> walletManagersFacade.getDefaultAddress(wallet.walletId, network).orEmpty() }
|
||||
?.let { network -> networksConverter.getAddressForWC(wallet.walletId, network).orEmpty() }
|
||||
.orEmpty()
|
||||
}
|
||||
val walletNetwork = when (method) {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ import com.tangem.domain.walletconnect.model.WcSolanaMethodName
|
|||
import com.tangem.domain.walletconnect.model.sdkcopy.WcSdkSessionRequest
|
||||
import com.tangem.domain.walletconnect.repository.WcSessionsManager
|
||||
import com.tangem.domain.walletconnect.usecase.method.WcMethodUseCase
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
import jakarta.inject.Inject
|
||||
|
||||
internal class WcSolanaNetwork(
|
||||
|
|
@ -30,7 +29,6 @@ internal class WcSolanaNetwork(
|
|||
private val sessionsManager: WcSessionsManager,
|
||||
private val factories: Factories,
|
||||
private val networksConverter: WcNetworksConverter,
|
||||
private val walletManagersFacade: WalletManagersFacade,
|
||||
) : WcRequestToUseCaseConverter {
|
||||
|
||||
override fun toWcMethodName(request: WcSdkSessionRequest): WcSolanaMethodName? {
|
||||
|
|
@ -52,7 +50,7 @@ internal class WcSolanaNetwork(
|
|||
val chainId = request.chainId.orEmpty()
|
||||
suspend fun anyExistNetwork() = networksConverter.mainOrAnyWalletNetworkForRequest(chainId, wallet)
|
||||
suspend fun anyAddress() = anyExistNetwork()
|
||||
?.let { network -> walletManagersFacade.getDefaultAddress(wallet.walletId, network).orEmpty() }
|
||||
?.let { network -> networksConverter.getAddressForWC(wallet.walletId, network).orEmpty() }
|
||||
.orEmpty()
|
||||
|
||||
val accountAddress = when (method) {
|
||||
|
|
|
|||
|
|
@ -9,11 +9,9 @@ import com.tangem.data.walletconnect.utils.WcNetworksConverter
|
|||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.walletconnect.model.WcSessionApprove
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
|
||||
internal class CaipNamespaceDelegate(
|
||||
private val namespaceConverters: Set<WcNamespaceConverter>,
|
||||
private val walletManagersFacade: WalletManagersFacade,
|
||||
private val wcNetworksConverter: WcNetworksConverter,
|
||||
) {
|
||||
|
||||
|
|
@ -36,7 +34,7 @@ internal class CaipNamespaceDelegate(
|
|||
}
|
||||
|
||||
suspend fun createCAIP10(userWalletId: UserWalletId, network: Network): CAIP10? {
|
||||
val address = walletManagersFacade.getDefaultAddress(userWalletId, network)
|
||||
val address = wcNetworksConverter.getAddressForWC(userWalletId, network)
|
||||
val chainId = allWcNetworks
|
||||
.find { (wcNetwork, _) -> network.rawId == wcNetwork.rawId }
|
||||
?.second
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
package com.tangem.data.walletconnect.utils
|
||||
|
||||
import com.reown.walletkit.client.Wallet
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.address.AddressType
|
||||
import com.tangem.blockchainsdk.utils.toBlockchain
|
||||
import com.tangem.data.common.currency.isCustomCoin
|
||||
import com.tangem.data.walletconnect.model.CAIP10
|
||||
import com.tangem.domain.account.producer.SingleAccountProducer
|
||||
|
|
@ -44,7 +47,7 @@ internal class WcNetworksConverter @Inject constructor(
|
|||
val allCoinNetwork = filterWalletNetworkForRequest(request.chainId.orEmpty(), session.wallet)
|
||||
|
||||
val requestNetwork = allCoinNetwork.find { network ->
|
||||
val address = walletManagersFacade.getDefaultAddress(wallet.walletId, network)
|
||||
val address = getAddressForWC(wallet.walletId, network)
|
||||
requestAddress.lowercase() == address?.lowercase()
|
||||
}
|
||||
return requestNetwork
|
||||
|
|
@ -60,7 +63,18 @@ internal class WcNetworksConverter @Inject constructor(
|
|||
|
||||
suspend fun allAddressForChain(rawChainId: String, wallet: UserWallet): List<String> {
|
||||
return filterWalletNetworkForRequest(rawChainId, wallet)
|
||||
.mapNotNull { walletManagersFacade.getDefaultAddress(wallet.walletId, it)?.lowercase() }
|
||||
.mapNotNull { getAddressForWC(wallet.walletId, it)?.lowercase() }
|
||||
}
|
||||
|
||||
suspend fun getAddressForWC(userWalletId: UserWalletId, network: Network): String? {
|
||||
return when (network.toBlockchain()) {
|
||||
Blockchain.XDC,
|
||||
Blockchain.XDCTestnet,
|
||||
-> walletManagersFacade.getAddresses(userWalletId, network)
|
||||
.find { address -> address.type == AddressType.Legacy }
|
||||
?.value
|
||||
else -> walletManagersFacade.getDefaultAddress(userWalletId, network)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -94,8 +108,8 @@ internal class WcNetworksConverter @Inject constructor(
|
|||
// find all derivation
|
||||
.filter { it.rawId == blockchain.id }
|
||||
// find equal address
|
||||
.firstOrNull {
|
||||
val walletAddress = walletManagersFacade.getDefaultAddress(wallet.walletId, it)
|
||||
.firstOrNull { network ->
|
||||
val walletAddress = getAddressForWC(wallet.walletId, network)
|
||||
walletAddress?.lowercase() == caip10.accountAddress.lowercase()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ internal class SdkTransactionHistoryItemConverter(
|
|||
SdkTransactionHistoryItem.TransactionStatus.Failed -> TxInfo.TransactionStatus.Failed
|
||||
SdkTransactionHistoryItem.TransactionStatus.Unconfirmed -> TxInfo.TransactionStatus.Unconfirmed
|
||||
},
|
||||
type = typeConverter.convert(value.type),
|
||||
type = typeConverter.convert(value.type to value.destinationType.toDomain()),
|
||||
amount = requireNotNull(value.amount.value) { "Transaction amount value must not be null" },
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,21 +1,27 @@
|
|||
package com.tangem.data.walletmanager.utils
|
||||
|
||||
import com.tangem.blockchain.transactionhistory.models.TransactionHistoryItem.TransactionType
|
||||
import com.tangem.blockchain.yieldsupply.providers.ethereum.yield.EthereumYieldSupplyEnterCallData
|
||||
import com.tangem.blockchain.yieldsupply.providers.ethereum.yield.EthereumYieldSupplyExitCallData
|
||||
import com.tangem.blockchain.yieldsupply.providers.ethereum.yield.EthereumYieldSupplyInitTokenCallData
|
||||
import com.tangem.blockchain.yieldsupply.providers.ethereum.yield.EthereumYieldSupplyReactivateTokenCallData
|
||||
import com.tangem.domain.models.network.TxInfo
|
||||
import com.tangem.domain.walletmanager.model.SmartContractMethod
|
||||
import com.tangem.utils.converter.Converter
|
||||
|
||||
internal class SdkTransactionTypeConverter(
|
||||
private val smartContractMethods: Map<String, SmartContractMethod>,
|
||||
) : Converter<TransactionType, TxInfo.TransactionType> {
|
||||
) : Converter<Pair<TransactionType, TxInfo.DestinationType>, TxInfo.TransactionType> {
|
||||
|
||||
override fun convert(value: TransactionType): TxInfo.TransactionType {
|
||||
return when (value) {
|
||||
override fun convert(value: Pair<TransactionType, TxInfo.DestinationType>): TxInfo.TransactionType {
|
||||
val (type, destination) = value
|
||||
|
||||
return when (type) {
|
||||
is TransactionType.ContractMethod -> {
|
||||
getTransactionType(methodName = smartContractMethods[value.id]?.name)
|
||||
getTransactionType(methodName = smartContractMethods[type.id]?.name, type.callData, destination)
|
||||
}
|
||||
is TransactionType.ContractMethodName -> {
|
||||
getTransactionType(methodName = value.name)
|
||||
getTransactionType(methodName = type.name, type.callData, destination)
|
||||
}
|
||||
is TransactionType.Transfer -> {
|
||||
TxInfo.TransactionType.Transfer
|
||||
|
|
@ -27,7 +33,7 @@ internal class SdkTransactionTypeConverter(
|
|||
TxInfo.TransactionType.Staking.Unstake
|
||||
}
|
||||
is TransactionType.TronStakingTransactionType.VoteWitnessContract -> {
|
||||
TxInfo.TransactionType.Staking.Vote(value.validatorAddress)
|
||||
TxInfo.TransactionType.Staking.Vote(type.validatorAddress)
|
||||
}
|
||||
is TransactionType.TronStakingTransactionType.WithdrawBalanceContract -> {
|
||||
TxInfo.TransactionType.Staking.ClaimRewards
|
||||
|
|
@ -38,7 +44,12 @@ internal class SdkTransactionTypeConverter(
|
|||
}
|
||||
}
|
||||
|
||||
private fun getTransactionType(methodName: String?): TxInfo.TransactionType {
|
||||
@Suppress("CyclomaticComplexMethod")
|
||||
private fun getTransactionType(
|
||||
methodName: String?,
|
||||
callData: String?,
|
||||
destination: TxInfo.DestinationType,
|
||||
): TxInfo.TransactionType {
|
||||
return when (methodName) {
|
||||
"transfer" -> TxInfo.TransactionType.Transfer
|
||||
"approve" -> TxInfo.TransactionType.Approve
|
||||
|
|
@ -59,11 +70,33 @@ internal class SdkTransactionTypeConverter(
|
|||
"withdrawRewardsPOL",
|
||||
-> TxInfo.TransactionType.Staking.ClaimRewards
|
||||
"redelegate" -> TxInfo.TransactionType.Staking.Restake
|
||||
"supplyEnter" -> TxInfo.TransactionType.YieldSupply.Enter
|
||||
"supplyExit" -> TxInfo.TransactionType.YieldSupply.Exit
|
||||
"yieldSend" -> TxInfo.TransactionType.YieldSupply.Send
|
||||
"enterProtocolByOwner" -> callData?.let { data ->
|
||||
TxInfo.TransactionType.YieldSupply.Enter(
|
||||
EthereumYieldSupplyEnterCallData.decode(data)?.tokenContractAddress.orEmpty(),
|
||||
)
|
||||
}
|
||||
"withdrawAndDeactivate" -> callData?.let { data ->
|
||||
TxInfo.TransactionType.YieldSupply.Exit(
|
||||
EthereumYieldSupplyExitCallData.decode(data)?.tokenContractAddress.orEmpty(),
|
||||
)
|
||||
}
|
||||
"deployYieldModule" -> TxInfo.TransactionType.YieldSupply.DeployContract(
|
||||
(destination as? TxInfo.DestinationType.Single)?.addressType?.address.orEmpty(),
|
||||
)
|
||||
"initYieldToken" -> callData?.let { data ->
|
||||
TxInfo.TransactionType.YieldSupply.InitializeToken(
|
||||
EthereumYieldSupplyInitTokenCallData.decode(data)?.tokenContractAddress.orEmpty(),
|
||||
)
|
||||
}
|
||||
"reactivateToken" -> callData?.let { data ->
|
||||
TxInfo.TransactionType.YieldSupply.ReactivateToken(
|
||||
EthereumYieldSupplyReactivateTokenCallData.decode(data)?.tokenContractAddress.orEmpty(),
|
||||
)
|
||||
}
|
||||
"supplyTopUp" -> TxInfo.TransactionType.YieldSupply.Topup
|
||||
null -> TxInfo.TransactionType.UnknownOperation
|
||||
else -> TxInfo.TransactionType.Operation(name = methodName.replaceFirstChar { it.titlecase() })
|
||||
}
|
||||
} ?: TxInfo.TransactionType.Operation(name = methodName?.replaceFirstChar { it.titlecase() }.orEmpty())
|
||||
}
|
||||
}
|
||||
|
|
@ -45,7 +45,7 @@ internal class TransactionDataToTxHistoryItemConverter(
|
|||
TransactionStatus.Confirmed -> TxInfo.TransactionStatus.Confirmed
|
||||
TransactionStatus.Unconfirmed -> TxInfo.TransactionStatus.Unconfirmed
|
||||
},
|
||||
type = getTransactionType(value.extras),
|
||||
type = getTransactionType(value),
|
||||
amount = amount,
|
||||
)
|
||||
}
|
||||
|
|
@ -99,16 +99,25 @@ internal class TransactionDataToTxHistoryItemConverter(
|
|||
)
|
||||
}
|
||||
|
||||
private fun getTransactionType(extras: TransactionExtras?): TxInfo.TransactionType {
|
||||
return when (extras) {
|
||||
private fun getTransactionType(transactionData: TransactionData.Uncompiled?): TxInfo.TransactionType {
|
||||
return when (val extras = transactionData?.extras) {
|
||||
is EthereumTransactionExtras -> {
|
||||
when (extras.callData) {
|
||||
is EthereumYieldSupplyDeployCallData,
|
||||
is EthereumYieldSupplyReactivateTokenCallData,
|
||||
is EthereumYieldSupplyInitTokenCallData,
|
||||
is EthereumYieldSupplyEnterCallData,
|
||||
-> TxInfo.TransactionType.YieldSupply.Enter
|
||||
is EthereumYieldSupplyExitCallData -> TxInfo.TransactionType.YieldSupply.Exit
|
||||
when (val callData = extras.callData) {
|
||||
is EthereumYieldSupplyDeployCallData -> TxInfo.TransactionType.YieldSupply.DeployContract(
|
||||
transactionData.destinationAddress,
|
||||
)
|
||||
is EthereumYieldSupplyReactivateTokenCallData -> TxInfo.TransactionType.YieldSupply.ReactivateToken(
|
||||
callData.tokenContractAddress,
|
||||
)
|
||||
is EthereumYieldSupplyInitTokenCallData -> TxInfo.TransactionType.YieldSupply.InitializeToken(
|
||||
callData.tokenContractAddress,
|
||||
)
|
||||
is EthereumYieldSupplyEnterCallData -> TxInfo.TransactionType.YieldSupply.Enter(
|
||||
callData.tokenContractAddress,
|
||||
)
|
||||
is EthereumYieldSupplyExitCallData -> TxInfo.TransactionType.YieldSupply.Exit(
|
||||
callData.tokenContractAddress,
|
||||
)
|
||||
is ApprovalERC20TokenCallData -> TxInfo.TransactionType.Approve
|
||||
else -> TxInfo.TransactionType.Transfer
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,10 @@ dependencies {
|
|||
/** Tangem SDKs */
|
||||
implementation(tangemDeps.blockchain)
|
||||
|
||||
// region AndroidX libraries
|
||||
implementation(deps.androidx.datastore)
|
||||
// endregion
|
||||
|
||||
/** Core */
|
||||
implementation(projects.core.datasource)
|
||||
implementation(projects.core.utils)
|
||||
|
|
|
|||
|
|
@ -12,6 +12,10 @@ import com.tangem.data.yield.supply.converters.YieldTokenChartConverter
|
|||
import com.tangem.datasource.api.common.response.getOrThrow
|
||||
import com.tangem.datasource.api.tangemTech.YieldSupplyApi
|
||||
import com.tangem.datasource.api.tangemTech.models.YieldSupplyChangeTokenStatusBody
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.datasource.local.preferences.PreferencesKeys
|
||||
import com.tangem.datasource.local.preferences.utils.get
|
||||
import com.tangem.datasource.local.preferences.utils.store
|
||||
import com.tangem.datasource.local.yieldsupply.YieldMarketsStore
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
|
|
@ -35,6 +39,7 @@ internal class DefaultYieldSupplyRepository(
|
|||
private val walletManagersFacade: WalletManagersFacade,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
private val analyticsExceptionHandler: AnalyticsExceptionHandler,
|
||||
private val appPreferencesStore: AppPreferencesStore,
|
||||
) : YieldSupplyRepository {
|
||||
|
||||
private val statusMap: MutableMap<String, YieldSupplyEnterStatus> = ConcurrentHashMap()
|
||||
|
|
@ -174,6 +179,14 @@ internal class DefaultYieldSupplyRepository(
|
|||
null
|
||||
}
|
||||
|
||||
override fun getShouldShowYieldPromoBanner(): Flow<Boolean> {
|
||||
return appPreferencesStore.get(PreferencesKeys.YIELD_SUPPLY_SHOULD_SHOW_MAIN_PROMO_KEY, true)
|
||||
}
|
||||
|
||||
override suspend fun setShouldShowYieldPromoBanner(shouldShow: Boolean) {
|
||||
appPreferencesStore.store(PreferencesKeys.YIELD_SUPPLY_SHOULD_SHOW_MAIN_PROMO_KEY, shouldShow)
|
||||
}
|
||||
|
||||
private fun Set<TxInfo>.hasYieldEnterTransactions(yieldAddress: String) = any {
|
||||
it.type == TxInfo.TransactionType.YieldSupply.Enter ||
|
||||
it.type == TxInfo.TransactionType.Approve &&
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import com.tangem.data.yield.supply.DefaultYieldSupplyRepository
|
|||
import com.tangem.data.yield.supply.DefaultYieldSupplyErrorResolver
|
||||
import com.tangem.data.yield.supply.DefaultYieldSupplyTransactionRepository
|
||||
import com.tangem.datasource.api.tangemTech.YieldSupplyApi
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.datasource.local.yieldsupply.YieldMarketsStore
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
import com.tangem.domain.yield.supply.YieldSupplyRepository
|
||||
|
|
@ -41,6 +42,7 @@ internal object YieldSupplyDataModule {
|
|||
walletManagersFacade: WalletManagersFacade,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
analyticsExceptionHandler: AnalyticsExceptionHandler,
|
||||
appPreferencesStore: AppPreferencesStore,
|
||||
): YieldSupplyRepository {
|
||||
return DefaultYieldSupplyRepository(
|
||||
yieldSupplyApi = yieldSupplyApi,
|
||||
|
|
@ -48,6 +50,7 @@ internal object YieldSupplyDataModule {
|
|||
dispatchers = dispatchers,
|
||||
walletManagersFacade = walletManagersFacade,
|
||||
analyticsExceptionHandler = analyticsExceptionHandler,
|
||||
appPreferencesStore = appPreferencesStore,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -57,7 +57,6 @@ sealed interface FeedbackEmailType {
|
|||
}
|
||||
|
||||
sealed class Visa : FeedbackEmailType {
|
||||
data class FailedIssueCard(override val walletMetaInfo: WalletMetaInfo) : Visa()
|
||||
|
||||
data class DirectUserRequest(override val walletMetaInfo: WalletMetaInfo) : Visa()
|
||||
|
||||
|
|
@ -68,6 +67,8 @@ sealed interface FeedbackEmailType {
|
|||
override val walletMetaInfo: WalletMetaInfo,
|
||||
) : Visa()
|
||||
|
||||
data class FailedIssueCard(override val walletMetaInfo: WalletMetaInfo) : Visa()
|
||||
|
||||
data class DisputeV2(
|
||||
val item: TangemPayTxHistoryItem,
|
||||
override val walletMetaInfo: WalletMetaInfo,
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ internal class FeedbackDataBuilder {
|
|||
|
||||
fun addTangemPayTxInfo(item: TangemPayTxHistoryItem) {
|
||||
builder.append(item.jsonRepresentation)
|
||||
builder.breakLine()
|
||||
}
|
||||
|
||||
fun addVisaTxInfo(txDetails: VisaTxDetails) {
|
||||
|
|
@ -108,6 +109,26 @@ internal class FeedbackDataBuilder {
|
|||
builder.appendKeyValue("App version", phoneInfo.appVersion)
|
||||
}
|
||||
|
||||
fun addTangemPayIssueType(type: FeedbackEmailType.Visa) {
|
||||
val issueType = when (type) {
|
||||
is FeedbackEmailType.Visa.Activation,
|
||||
is FeedbackEmailType.Visa.DirectUserRequest,
|
||||
is FeedbackEmailType.Visa.Dispute,
|
||||
is FeedbackEmailType.Visa.FeatureIsBeta,
|
||||
is FeedbackEmailType.Visa.Withdrawal,
|
||||
-> return
|
||||
is FeedbackEmailType.Visa.DisputeV2 -> when (type.item) {
|
||||
is TangemPayTxHistoryItem.Collateral -> "Receive/Withdraw"
|
||||
is TangemPayTxHistoryItem.Fee,
|
||||
is TangemPayTxHistoryItem.Spend,
|
||||
is TangemPayTxHistoryItem.Payment,
|
||||
-> "Transaction"
|
||||
}
|
||||
is FeedbackEmailType.Visa.FailedIssueCard -> "Card issuing"
|
||||
}
|
||||
builder.appendKeyValue("Issue type", issueType)
|
||||
}
|
||||
|
||||
fun addBlockchainError(info: BlockchainInfo, error: BlockchainErrorInfo) {
|
||||
builder.appendKeyValue("Blockchain", info.blockchain)
|
||||
builder.appendAddresses(
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@ import com.tangem.domain.feedback.models.FeedbackEmail
|
|||
import com.tangem.domain.feedback.models.FeedbackEmailType
|
||||
import com.tangem.domain.feedback.repository.FeedbackRepository
|
||||
import com.tangem.domain.feedback.utils.*
|
||||
import java.io.File
|
||||
|
||||
private const val BINDER_MAX_SIZE_BYTES = 500_000 // Safe limit under Android's 1MB Binder limit
|
||||
|
||||
/**
|
||||
* Get email with feedback for support
|
||||
|
|
@ -29,22 +32,30 @@ class SendFeedbackEmailUseCase(
|
|||
address = getAddress(type),
|
||||
subject = emailSubjectResolver.resolve(type),
|
||||
message = createMessage(type),
|
||||
file = feedbackRepository.getZipLogFile(),
|
||||
file = getFile(type),
|
||||
)
|
||||
|
||||
feedbackRepository.sendEmail(email)
|
||||
}
|
||||
|
||||
private suspend fun getFile(type: FeedbackEmailType): File? {
|
||||
return if (type.isVisaEmail()) {
|
||||
null
|
||||
} else {
|
||||
feedbackRepository.getZipLogFile()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getAddress(type: FeedbackEmailType): String {
|
||||
return when {
|
||||
type is FeedbackEmailType.Visa || type.walletMetaInfo?.isVisa == true -> TANGEM_VISA_SUPPORT_EMAIL
|
||||
type.isVisaEmail() -> TANGEM_VISA_SUPPORT_EMAIL
|
||||
type.walletMetaInfo?.isStart2Coin == true -> START2COIN_SUPPORT_EMAIL
|
||||
else -> TANGEM_SUPPORT_EMAIL
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun createMessage(type: FeedbackEmailType): String {
|
||||
return StringBuilder().apply {
|
||||
val fullMessage = buildString {
|
||||
val title = emailMessageTitleResolver.resolve(type)
|
||||
append(title)
|
||||
|
||||
|
|
@ -54,7 +65,25 @@ class SendFeedbackEmailUseCase(
|
|||
|
||||
val body = emailMessageBodyResolver.resolve(type)
|
||||
append(body)
|
||||
}.toString()
|
||||
}
|
||||
|
||||
return truncateMessageIfNeeded(fullMessage)
|
||||
}
|
||||
|
||||
private fun truncateMessageIfNeeded(message: String): String {
|
||||
val messageBytes = message.toByteArray(Charsets.UTF_8)
|
||||
|
||||
return if (messageBytes.size > BINDER_MAX_SIZE_BYTES) {
|
||||
// Find a safe truncation point (avoid cutting in middle of UTF-8 chars)
|
||||
val truncatedBytes = messageBytes.sliceArray(0 until BINDER_MAX_SIZE_BYTES)
|
||||
String(truncatedBytes, Charsets.UTF_8)
|
||||
} else {
|
||||
message
|
||||
}
|
||||
}
|
||||
|
||||
private fun FeedbackEmailType.isVisaEmail(): Boolean {
|
||||
return this is FeedbackEmailType.Visa || this.walletMetaInfo?.isVisa == true
|
||||
}
|
||||
|
||||
private fun StringBuilder.appendDisclaimerIfNeeded(type: FeedbackEmailType): StringBuilder {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import com.tangem.domain.feedback.FeedbackDataBuilder
|
|||
import com.tangem.domain.feedback.models.FeedbackEmailType
|
||||
import com.tangem.domain.feedback.models.WalletMetaInfo
|
||||
import com.tangem.domain.feedback.repository.FeedbackRepository
|
||||
import com.tangem.domain.visa.model.TangemPayTxHistoryItem
|
||||
import com.tangem.domain.visa.model.VisaTxDetails
|
||||
|
||||
/**
|
||||
|
|
@ -34,31 +33,39 @@ internal class EmailMessageBodyResolver(
|
|||
-> addPhoneInfoBody()
|
||||
is FeedbackEmailType.Visa.Activation -> addUserRequestBody(type.walletMetaInfo)
|
||||
is FeedbackEmailType.Visa.DirectUserRequest -> addUserRequestBody(type.walletMetaInfo)
|
||||
is FeedbackEmailType.Visa.FailedIssueCard -> addUserRequestBody(type.walletMetaInfo)
|
||||
is FeedbackEmailType.Visa.Dispute -> addVisaRequestBody(type.walletMetaInfo, type.visaTxDetails)
|
||||
is FeedbackEmailType.Visa.DisputeV2 -> addTangemPayRequestBody(type.walletMetaInfo, type.item)
|
||||
is FeedbackEmailType.Visa.FailedIssueCard -> addTangemPayFailedIssuingCardBody(type)
|
||||
is FeedbackEmailType.Visa.DisputeV2 -> addTangemPayDisputeRequestBody(type)
|
||||
is FeedbackEmailType.Visa.Withdrawal -> addTangemPayWithdrawalRequestBody(type)
|
||||
is FeedbackEmailType.Visa.FeatureIsBeta -> addTangemPayBetaRequestBody(type.walletMetaInfo)
|
||||
is FeedbackEmailType.Visa.FeatureIsBeta -> addTangemPayBetaRequestBody(type)
|
||||
}
|
||||
|
||||
return build()
|
||||
}
|
||||
|
||||
private suspend fun FeedbackDataBuilder.addTangemPayRequestBody(
|
||||
walletMetaInfo: WalletMetaInfo,
|
||||
item: TangemPayTxHistoryItem,
|
||||
) {
|
||||
addUserRequestBody(walletMetaInfo)
|
||||
private fun FeedbackDataBuilder.addTangemPayFailedIssuingCardBody(type: FeedbackEmailType.Visa.FailedIssueCard) {
|
||||
addTangemPayPhoneInfoBody(type)
|
||||
addDelimiter()
|
||||
addTangemPayTxInfo(item)
|
||||
type.walletMetaInfo.userWalletId?.let { userWalletId ->
|
||||
addUserWalletId(userWalletId = userWalletId.stringValue)
|
||||
}
|
||||
}
|
||||
|
||||
private fun FeedbackDataBuilder.addTangemPayBetaRequestBody(walletMetaInfo: WalletMetaInfo) {
|
||||
addPhoneInfoBody()
|
||||
private fun FeedbackDataBuilder.addTangemPayDisputeRequestBody(type: FeedbackEmailType.Visa.DisputeV2) {
|
||||
addTangemPayPhoneInfoBody(type = type)
|
||||
addDelimiter()
|
||||
walletMetaInfo.userWalletId?.let { userWalletId ->
|
||||
addTangemPayTxInfo(type.item)
|
||||
addDelimiter()
|
||||
type.walletMetaInfo.userWalletId?.let { userWalletId ->
|
||||
addUserWalletId(userWalletId = userWalletId.stringValue)
|
||||
}
|
||||
}
|
||||
|
||||
private fun FeedbackDataBuilder.addTangemPayBetaRequestBody(type: FeedbackEmailType.Visa) {
|
||||
addTangemPayPhoneInfoBody(type)
|
||||
addDelimiter()
|
||||
type.walletMetaInfo?.userWalletId?.let { userWalletId ->
|
||||
addUserWalletId(userWalletId = userWalletId.stringValue)
|
||||
addDelimiter()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -122,6 +129,11 @@ internal class EmailMessageBodyResolver(
|
|||
addPhoneInfo(phoneInfo = feedbackRepository.getPhoneInfo())
|
||||
}
|
||||
|
||||
private fun FeedbackDataBuilder.addTangemPayPhoneInfoBody(type: FeedbackEmailType.Visa) {
|
||||
addPhoneInfo(phoneInfo = feedbackRepository.getPhoneInfo())
|
||||
addTangemPayIssueType(type)
|
||||
}
|
||||
|
||||
private suspend fun FeedbackDataBuilder.addTransactionSendingProblemBody(walletMetaInfo: WalletMetaInfo) {
|
||||
addUserWalletMetaInfo(walletMetaInfo)
|
||||
addDelimiter()
|
||||
|
|
|
|||
|
|
@ -205,32 +205,32 @@
|
|||
"0xcbeda14c": {
|
||||
"info": "yieldModule",
|
||||
"source": "https://github.com/tangem/tangem-yield-module-contracts/",
|
||||
"name": "supply"
|
||||
"name": "deployYieldModule"
|
||||
},
|
||||
"0x79be55f7": {
|
||||
"info": "yieldModule",
|
||||
"source": "https://github.com/tangem/tangem-yield-module-contracts/",
|
||||
"name": "supplyEnter"
|
||||
"name": "enterProtocolByOwner"
|
||||
},
|
||||
"0xc65e6dcf": {
|
||||
"info": "yieldModule",
|
||||
"source": "https://github.com/tangem/tangem-yield-module-contracts/",
|
||||
"name": "supplyExit"
|
||||
"name": "withdrawAndDeactivate"
|
||||
},
|
||||
"0xebd4b81c": {
|
||||
"info": "yieldModule",
|
||||
"source": "https://github.com/tangem/tangem-yield-module-contracts/",
|
||||
"name": "supply"
|
||||
"name": "initYieldToken"
|
||||
},
|
||||
"0xc478e956": {
|
||||
"info": "yieldModule",
|
||||
"source": "https://github.com/tangem/tangem-yield-module-contracts/",
|
||||
"name": "supply"
|
||||
"name": "reactivateToken"
|
||||
},
|
||||
"0x0779afe6": {
|
||||
"info": "yieldModule",
|
||||
"source": "https://github.com/tangem/tangem-yield-module-contracts/",
|
||||
"name": "transfer"
|
||||
"name": "yieldSend"
|
||||
},
|
||||
"0xb9de6a93": {
|
||||
"info": "yieldModule",
|
||||
|
|
|
|||
|
|
@ -11,9 +11,9 @@ fun CryptoCurrencyStatus.hasNotSuppliedAmount(): Boolean {
|
|||
return notSupplied > BigDecimal.ZERO
|
||||
}
|
||||
|
||||
fun CryptoCurrencyStatus.shouldShowNotSuppliedInfoIcon(minAmount: BigDecimal): Boolean {
|
||||
fun CryptoCurrencyStatus.shouldShowNotSuppliedInfoIcon(dustAmount: BigDecimal): Boolean {
|
||||
val notSupplied = notSuppliedAmountOrNull() ?: return false
|
||||
return notSupplied >= minAmount
|
||||
return notSupplied >= dustAmount
|
||||
}
|
||||
|
||||
fun CryptoCurrencyStatus.notSuppliedAmountOrNull(): BigDecimal? {
|
||||
|
|
|
|||
|
|
@ -110,14 +110,32 @@ data class TxInfo(
|
|||
@Serializable
|
||||
sealed interface YieldSupply : TransactionType {
|
||||
|
||||
@Serializable
|
||||
data object Enter : YieldSupply
|
||||
val address: String?
|
||||
|
||||
@Serializable
|
||||
data object Exit : YieldSupply
|
||||
data class Enter(override val address: String) : YieldSupply
|
||||
|
||||
@Serializable
|
||||
data object Topup : YieldSupply
|
||||
data class Exit(override val address: String) : YieldSupply
|
||||
|
||||
@Serializable
|
||||
data object Topup : YieldSupply {
|
||||
override val address: String? = null
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data object Send : YieldSupply {
|
||||
override val address: String? = null
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class DeployContract(override val address: String) : YieldSupply
|
||||
|
||||
@Serializable
|
||||
data class ReactivateToken(override val address: String) : YieldSupply
|
||||
|
||||
@Serializable
|
||||
data class InitializeToken(override val address: String) : YieldSupply
|
||||
}
|
||||
|
||||
@Serializable
|
||||
|
|
|
|||
|
|
@ -30,4 +30,5 @@ enum class PromoId {
|
|||
Sepa,
|
||||
VisaPresale,
|
||||
BlackFriday,
|
||||
OnePlusOne,
|
||||
}
|
||||
|
|
@ -32,6 +32,7 @@ class ShouldShowPromoWalletUseCase(
|
|||
PromoId.Referral,
|
||||
PromoId.VisaPresale,
|
||||
PromoId.BlackFriday,
|
||||
PromoId.OnePlusOne,
|
||||
-> true
|
||||
PromoId.Sepa -> {
|
||||
val walletFirstUsageDate = settingsRepository.getWalletFirstUsageDate()
|
||||
|
|
|
|||
|
|
@ -59,5 +59,6 @@ sealed class PromoAnalyticsEvent(
|
|||
Empty("Empty"),
|
||||
Sepa("Sepa"),
|
||||
BlackFriday("Black Friday"),
|
||||
OnePlusOne("One-Plus-One"),
|
||||
}
|
||||
}
|
||||
|
|
@ -10,7 +10,7 @@ sealed class TangemPayAnalyticsEvents(
|
|||
|
||||
class ActivationScreenOpened : TangemPayAnalyticsEvents(
|
||||
categoryName = "Visa Onboarding",
|
||||
event = "Activation Screen Opened",
|
||||
event = "Visa Activation Screen Opened",
|
||||
)
|
||||
|
||||
class ViewTermsClicked : TangemPayAnalyticsEvents(
|
||||
|
|
@ -43,6 +43,11 @@ sealed class TangemPayAnalyticsEvents(
|
|||
event = "Button - Visa Receive",
|
||||
)
|
||||
|
||||
class AddFundsClicked : TangemPayAnalyticsEvents(
|
||||
categoryName = "Visa Screen",
|
||||
event = "Button - Visa Add Funds",
|
||||
)
|
||||
|
||||
class SwapClicked : TangemPayAnalyticsEvents(
|
||||
categoryName = "Visa Screen",
|
||||
event = "Button - Visa Swap",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
package com.tangem.domain.yield.supply.models
|
||||
|
||||
data class YieldSupplyRewardBalance(
|
||||
val fiatBalance: String?,
|
||||
val cryptoBalance: String?,
|
||||
) {
|
||||
companion object {
|
||||
fun empty() = YieldSupplyRewardBalance(null, null)
|
||||
}
|
||||
}
|
||||
|
|
@ -108,4 +108,8 @@ interface YieldSupplyRepository {
|
|||
userWalletId: UserWalletId,
|
||||
cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
): YieldSupplyEnterStatus?
|
||||
|
||||
fun getShouldShowYieldPromoBanner(): Flow<Boolean>
|
||||
|
||||
suspend fun setShouldShowYieldPromoBanner(shouldShow: Boolean)
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ package com.tangem.domain.yield.supply.usecase
|
|||
import com.tangem.domain.yield.supply.YieldSupplyRepository
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import java.math.BigDecimal
|
||||
|
||||
/**
|
||||
* Emits a map of APY values per token.
|
||||
|
|
@ -15,11 +16,11 @@ class YieldSupplyApyFlowUseCase(
|
|||
private val yieldSupplyRepository: YieldSupplyRepository,
|
||||
) {
|
||||
|
||||
operator fun invoke(): Flow<Map<String, String>> {
|
||||
operator fun invoke(): Flow<Map<String, BigDecimal>> {
|
||||
return yieldSupplyRepository.getMarketsFlow()
|
||||
.map { yieldMarketTokenList ->
|
||||
yieldMarketTokenList.filter { it.isActive }.associate { token ->
|
||||
token.yieldSupplyKey to token.apy.toString()
|
||||
token.yieldSupplyKey to token.apy
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
package com.tangem.domain.yield.supply.usecase
|
||||
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import java.math.BigDecimal
|
||||
|
||||
class YieldSupplyGetDustMinAmountUseCase {
|
||||
|
||||
operator fun invoke(minAmount: BigDecimal, appCurrency: AppCurrency): BigDecimal {
|
||||
return if (appCurrency.code in SUPPORTED_DUST_CURRENCIES) {
|
||||
DUST_MIN_AMOUNT
|
||||
} else {
|
||||
minAmount.stripTrailingZeros()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val DUST_MIN_AMOUNT = BigDecimal("0.1")
|
||||
private val SUPPORTED_DUST_CURRENCIES = setOf("EUR", "USD", "AUD", "CAD", "GBP")
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,13 @@
|
|||
package com.tangem.domain.yield.supply.usecase
|
||||
|
||||
import com.tangem.core.ui.format.bigdecimal.anyDecimals
|
||||
import com.tangem.core.ui.format.bigdecimal.crypto
|
||||
import com.tangem.core.ui.format.bigdecimal.fiat
|
||||
import com.tangem.core.ui.format.bigdecimal.format
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.yield.supply.models.YieldSupplyRewardBalance
|
||||
import com.tangem.domain.yield.supply.YieldSupplyRepository
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.delay
|
||||
|
|
@ -22,7 +24,7 @@ class YieldSupplyGetRewardsBalanceUseCase(
|
|||
private val dispatcherProvider: CoroutineDispatcherProvider,
|
||||
) {
|
||||
|
||||
operator fun invoke(status: CryptoCurrencyStatus, appCurrency: AppCurrency): Flow<String> = flow {
|
||||
operator fun invoke(status: CryptoCurrencyStatus, appCurrency: AppCurrency): Flow<YieldSupplyRewardBalance> = flow {
|
||||
val cryptoAmount = status.value.amount
|
||||
val fiatRate = status.value.fiatRate
|
||||
|
||||
|
|
@ -30,11 +32,7 @@ class YieldSupplyGetRewardsBalanceUseCase(
|
|||
return@flow
|
||||
}
|
||||
|
||||
val amount = if (cryptoAmount != null && fiatRate != null) {
|
||||
cryptoAmount.multiply(fiatRate)
|
||||
} else {
|
||||
return@flow
|
||||
}
|
||||
if (cryptoAmount == null) return@flow
|
||||
|
||||
val tokenAddress = (status.currency as? CryptoCurrency.Token)?.contractAddress ?: return@flow
|
||||
val apy = try {
|
||||
|
|
@ -50,37 +48,57 @@ class YieldSupplyGetRewardsBalanceUseCase(
|
|||
return@flow
|
||||
}
|
||||
|
||||
val initialPerTickDelta = amount
|
||||
.multiply(apyFraction)
|
||||
.multiply(TICK_SECONDS_BD)
|
||||
.divide(SECONDS_PER_YEAR_BD, SCALE, RoundingMode.HALF_UP)
|
||||
.abs()
|
||||
val initialPerTickDeltaCrypto = perTickDelta(cryptoAmount, apyFraction).abs()
|
||||
|
||||
val minVisibleDecimals = calculateMinVisibleDecimals(initialPerTickDelta)
|
||||
val minVisibleDecimalsCrypto = calculateMinVisibleDecimals(
|
||||
perTickDeltaAbs = initialPerTickDeltaCrypto,
|
||||
maxDecimals = status.currency.decimals,
|
||||
)
|
||||
|
||||
var currentBalance: BigDecimal = amount
|
||||
val fiatAmountStart = fiatRate?.let { cryptoAmount.multiply(it) }
|
||||
val minVisibleDecimalsFiat = fiatAmountStart?.let { amount ->
|
||||
val initialPerTickDeltaFiat = perTickDelta(amount, apyFraction).abs()
|
||||
calculateMinVisibleDecimals(
|
||||
perTickDeltaAbs = initialPerTickDeltaFiat,
|
||||
maxDecimals = FIAT_MAX_DECIMALS,
|
||||
)
|
||||
}
|
||||
|
||||
var currentCryptoBalance: BigDecimal = cryptoAmount
|
||||
var currentFiatBalance: BigDecimal? = fiatAmountStart
|
||||
while (true) {
|
||||
val fiatBalanceFormatted: String? = currentFiatBalance?.format {
|
||||
fiat(
|
||||
fiatCurrencyCode = appCurrency.code,
|
||||
fiatCurrencySymbol = appCurrency.symbol,
|
||||
).anyDecimals(decimals = minVisibleDecimalsFiat ?: FIAT_MIN_DECIMALS)
|
||||
}
|
||||
|
||||
val cryptoBalanceFormatted: String = currentCryptoBalance.format {
|
||||
crypto(status.currency).anyDecimals(
|
||||
maxDecimals = minVisibleDecimalsCrypto,
|
||||
minDecimals = minVisibleDecimalsCrypto,
|
||||
)
|
||||
}
|
||||
|
||||
emit(
|
||||
currentBalance.format {
|
||||
fiat(
|
||||
fiatCurrencyCode = appCurrency.code,
|
||||
fiatCurrencySymbol = appCurrency.symbol,
|
||||
).anyDecimals(decimals = minVisibleDecimals)
|
||||
},
|
||||
YieldSupplyRewardBalance(fiatBalance = fiatBalanceFormatted, cryptoBalance = cryptoBalanceFormatted),
|
||||
)
|
||||
|
||||
val perTickDelta = currentBalance
|
||||
.multiply(apyFraction)
|
||||
.multiply(TICK_SECONDS_BD)
|
||||
.divide(SECONDS_PER_YEAR_BD, SCALE, RoundingMode.HALF_UP)
|
||||
val perTickDeltaCrypto = perTickDelta(currentCryptoBalance, apyFraction)
|
||||
|
||||
currentBalance = currentBalance.add(perTickDelta)
|
||||
currentCryptoBalance = currentCryptoBalance.add(perTickDeltaCrypto)
|
||||
|
||||
currentFiatBalance = currentFiatBalance?.let { current ->
|
||||
val perTickDeltaFiat = perTickDelta(current, apyFraction)
|
||||
current.add(perTickDeltaFiat)
|
||||
}
|
||||
|
||||
delay(TICK_MILLIS)
|
||||
}
|
||||
}.flowOn(dispatcherProvider.default)
|
||||
|
||||
private fun calculateMinVisibleDecimals(perTickDeltaAbs: BigDecimal): Int {
|
||||
private fun calculateMinVisibleDecimals(perTickDeltaAbs: BigDecimal, maxDecimals: Int): Int {
|
||||
if (perTickDeltaAbs <= BigDecimal.ZERO) return MIN_DECIMALS
|
||||
|
||||
val perTickAsDouble = perTickDeltaAbs.toDouble()
|
||||
|
|
@ -88,20 +106,28 @@ class YieldSupplyGetRewardsBalanceUseCase(
|
|||
|
||||
val safe = if (perTickAsDouble <= 0.0) EPSILON else perTickAsDouble
|
||||
val raw = ceil(-ln(safe) / LN_10)
|
||||
return raw.toInt().coerceIn(MIN_DECIMALS, MAX_DECIMALS)
|
||||
return raw.toInt().coerceIn(MIN_DECIMALS, maxDecimals)
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val TICK_MILLIS: Long = 300
|
||||
private val TICK_SECONDS_BD = BigDecimal("0.3")
|
||||
private val SECONDS_PER_YEAR_BD = BigDecimal("31536000") // 365 * 24 * 60 * 60
|
||||
private val HUNDRED_BD = BigDecimal("100")
|
||||
private const val SCALE = 18
|
||||
private fun perTickDelta(amount: BigDecimal, apyFraction: BigDecimal): BigDecimal {
|
||||
return amount
|
||||
.multiply(apyFraction)
|
||||
.multiply(TICK_SECONDS_BD)
|
||||
.divide(SECONDS_PER_YEAR_BD, SCALE, RoundingMode.HALF_UP)
|
||||
}
|
||||
|
||||
private const val MIN_DECIMALS = 3
|
||||
private const val MAX_DECIMALS = 12
|
||||
companion object {
|
||||
internal const val TICK_MILLIS: Long = 800
|
||||
internal val TICK_SECONDS_BD: BigDecimal = BigDecimal("0.8")
|
||||
internal val SECONDS_PER_YEAR_BD: BigDecimal = BigDecimal("31536000") // 365 * 24 * 60 * 60
|
||||
internal val HUNDRED_BD: BigDecimal = BigDecimal("100")
|
||||
internal const val SCALE: Int = 18
|
||||
|
||||
private val LN_10 = ln(10.0)
|
||||
private const val EPSILON = 1e-18
|
||||
internal const val MIN_DECIMALS: Int = 3
|
||||
internal const val FIAT_MIN_DECIMALS: Int = 2
|
||||
internal const val FIAT_MAX_DECIMALS: Int = 12
|
||||
|
||||
internal val LN_10: Double = ln(10.0)
|
||||
internal const val EPSILON: Double = 1e-18
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.tangem.domain.yield.supply.usecase
|
||||
|
||||
import com.tangem.domain.yield.supply.YieldSupplyRepository
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
class YieldSupplyGetShouldShowMainPromoUseCase(
|
||||
private val yieldSupplyRepository: YieldSupplyRepository,
|
||||
) {
|
||||
|
||||
operator fun invoke(): Flow<Boolean> {
|
||||
return yieldSupplyRepository.getShouldShowYieldPromoBanner()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package com.tangem.domain.yield.supply.usecase
|
||||
|
||||
import com.tangem.domain.yield.supply.YieldSupplyRepository
|
||||
|
||||
class YieldSupplySetShouldShowMainPromoUseCase(
|
||||
private val yieldSupplyRepository: YieldSupplyRepository,
|
||||
) {
|
||||
|
||||
suspend operator fun invoke(shouldShow: Boolean) {
|
||||
yieldSupplyRepository.setShouldShowYieldPromoBanner(shouldShow)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
package com.tangem.domain.yield.supply.usecase
|
||||
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.math.BigDecimal
|
||||
|
||||
class YieldSupplyGetDustMinAmountUseCaseTest {
|
||||
|
||||
private val useCase = YieldSupplyGetDustMinAmountUseCase()
|
||||
|
||||
@Test
|
||||
fun `GIVEN supported currency WHEN invoke THEN return dust min amount`() {
|
||||
val minAmount = BigDecimal("123.456")
|
||||
val appCurrency = AppCurrency(code = "EUR", name = "Euro", symbol = "€")
|
||||
|
||||
val result = useCase(minAmount, appCurrency)
|
||||
|
||||
assertThat(result).isEqualTo(BigDecimal("0.1"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN unsupported currency WHEN invoke THEN return min amount stripped`() {
|
||||
val minAmount = BigDecimal("1.2300")
|
||||
val appCurrency = AppCurrency(code = "JPY", name = "Japanese Yen", symbol = "¥")
|
||||
|
||||
val result = useCase(minAmount, appCurrency)
|
||||
|
||||
assertThat(result).isEqualTo(BigDecimal("1.23"))
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ import com.google.common.truth.Truth.assertThat
|
|||
import com.tangem.core.ui.format.bigdecimal.format
|
||||
import com.tangem.core.ui.format.bigdecimal.fiat
|
||||
import com.tangem.core.ui.format.bigdecimal.anyDecimals
|
||||
import com.tangem.core.ui.format.bigdecimal.crypto
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
|
|
@ -11,6 +12,7 @@ import com.tangem.domain.models.network.Network
|
|||
import com.tangem.domain.models.network.NetworkAddress
|
||||
import com.tangem.domain.yield.supply.YieldSupplyRepository
|
||||
import com.tangem.domain.yield.supply.models.YieldMarketToken
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyGetRewardsBalanceUseCase.Companion.TICK_MILLIS
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.mockk
|
||||
|
|
@ -26,7 +28,6 @@ import org.junit.jupiter.api.Test
|
|||
import java.math.BigDecimal
|
||||
import java.math.RoundingMode
|
||||
import kotlin.math.ceil
|
||||
import kotlin.math.ln
|
||||
|
||||
class YieldSupplyGetRewardsBalanceUseCaseTest {
|
||||
|
||||
|
|
@ -165,9 +166,9 @@ class YieldSupplyGetRewardsBalanceUseCaseTest {
|
|||
val deferred = async { useCase(status, appCurrency).take(3).toList() }
|
||||
|
||||
testScheduler.advanceUntilIdle()
|
||||
advanceTimeBy(300)
|
||||
advanceTimeBy(TICK_MILLIS)
|
||||
testScheduler.advanceUntilIdle()
|
||||
advanceTimeBy(300)
|
||||
advanceTimeBy(TICK_MILLIS)
|
||||
testScheduler.advanceUntilIdle()
|
||||
|
||||
val collected = deferred.await()
|
||||
|
|
@ -175,25 +176,147 @@ class YieldSupplyGetRewardsBalanceUseCaseTest {
|
|||
|
||||
val expectedDecimals = calculateMinVisibleDecimalsForTest(initialPerTickDelta(amount, apy))
|
||||
|
||||
val firstExpected = amount.format { fiat(
|
||||
appCurrency.code,
|
||||
appCurrency.symbol,
|
||||
).anyDecimals(decimals = expectedDecimals) }
|
||||
assertThat(collected[0]).isEqualTo(firstExpected)
|
||||
val firstExpected = amount.format {
|
||||
fiat(
|
||||
appCurrency.code,
|
||||
appCurrency.symbol,
|
||||
).anyDecimals(decimals = expectedDecimals)
|
||||
}
|
||||
assertThat(collected[0].fiatBalance).isEqualTo(firstExpected)
|
||||
|
||||
val firstNext = nextBalance(amount, apy)
|
||||
val secondExpected = firstNext.format { fiat(
|
||||
appCurrency.code,
|
||||
appCurrency.symbol,
|
||||
).anyDecimals(decimals = expectedDecimals) }
|
||||
assertThat(collected[1]).isEqualTo(secondExpected)
|
||||
val secondExpected = firstNext.format {
|
||||
fiat(
|
||||
appCurrency.code,
|
||||
appCurrency.symbol,
|
||||
).anyDecimals(decimals = expectedDecimals)
|
||||
}
|
||||
assertThat(collected[1].fiatBalance).isEqualTo(secondExpected)
|
||||
|
||||
val secondNext = nextBalance(firstNext, apy)
|
||||
val thirdExpected = secondNext.format { fiat(
|
||||
appCurrency.code,
|
||||
appCurrency.symbol,
|
||||
).anyDecimals(decimals = expectedDecimals) }
|
||||
assertThat(collected[2]).isEqualTo(thirdExpected)
|
||||
val thirdExpected = secondNext.format {
|
||||
fiat(
|
||||
appCurrency.code,
|
||||
appCurrency.symbol,
|
||||
).anyDecimals(decimals = expectedDecimals)
|
||||
}
|
||||
assertThat(collected[2].fiatBalance).isEqualTo(thirdExpected)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN polygon USDT0 Loaded status WHEN invoke THEN emit formatted balances`() = runTest {
|
||||
val network = Network(
|
||||
id = Network.ID(Network.RawID("POLYGON"), Network.DerivationPath.Card("m/44'/60'/0'/0/0")),
|
||||
backendId = "polygon-pos",
|
||||
name = "Polygon",
|
||||
currencySymbol = "POL",
|
||||
derivationPath = Network.DerivationPath.Card("m/44'/60'/0'/0/0"),
|
||||
isTestnet = false,
|
||||
standardType = Network.StandardType.Unspecified("Polygon"),
|
||||
hasFiatFeeRate = true,
|
||||
canHandleTokens = true,
|
||||
transactionExtrasType = Network.TransactionExtrasType.NONE,
|
||||
nameResolvingType = Network.NameResolvingType.NONE,
|
||||
)
|
||||
val tokenId = CryptoCurrency.ID(
|
||||
prefix = CryptoCurrency.ID.Prefix.TOKEN_PREFIX,
|
||||
body = CryptoCurrency.ID.Body.NetworkId(network.rawId),
|
||||
suffix = CryptoCurrency.ID.Suffix.RawID("usdt0", "0xc2132d05d31c914a87c6611c10748aeb04b58e8f"),
|
||||
)
|
||||
val currency = CryptoCurrency.Token(
|
||||
id = tokenId,
|
||||
network = network,
|
||||
name = "USDT0",
|
||||
symbol = "USDT0",
|
||||
decimals = 6,
|
||||
iconUrl = "https://s3.eu-central-1.amazonaws.com/tangem.api/coins/large/usdt0.png",
|
||||
isCustom = false,
|
||||
contractAddress = "0xc2132d05d31c914a87c6611c10748aeb04b58e8f",
|
||||
)
|
||||
|
||||
val amount = BigDecimal("9.241136")
|
||||
val fiatRate = BigDecimal("0.9999761277273864")
|
||||
val status = CryptoCurrencyStatus(
|
||||
currency = currency,
|
||||
value = CryptoCurrencyStatus.Loaded(
|
||||
amount = amount,
|
||||
fiatAmount = amount.multiply(fiatRate),
|
||||
fiatRate = fiatRate,
|
||||
priceChange = BigDecimal("-0.000058200000000008245"),
|
||||
stakingBalance = null,
|
||||
yieldSupplyStatus = null,
|
||||
hasCurrentNetworkTransactions = false,
|
||||
pendingTransactions = emptySet(),
|
||||
networkAddress = NetworkAddress.Single(
|
||||
NetworkAddress.Address(
|
||||
value = "0xb71fa0E20ba8579B3ec51cC79aaa84Bf5982BB49",
|
||||
type = NetworkAddress.Address.Type.Primary,
|
||||
),
|
||||
),
|
||||
sources = CryptoCurrencyStatus.Sources(),
|
||||
),
|
||||
)
|
||||
|
||||
val apy = BigDecimal("5.0")
|
||||
coEvery { repository.getCachedMarkets() } returns listOf(
|
||||
YieldMarketToken(
|
||||
tokenAddress = currency.contractAddress,
|
||||
chainId = 137,
|
||||
apy = apy,
|
||||
isActive = true,
|
||||
maxFeeNative = BigDecimal.ZERO,
|
||||
maxFeeUSD = BigDecimal.ZERO,
|
||||
backendId = "polygon-pos",
|
||||
),
|
||||
)
|
||||
|
||||
val dispatcherProvider = testDispatcherProvider(this)
|
||||
val useCase = YieldSupplyGetRewardsBalanceUseCase(repository, dispatcherProvider)
|
||||
val appCurrency = AppCurrency.Default
|
||||
|
||||
val deferred = async { useCase(status, appCurrency).take(2).toList() }
|
||||
|
||||
testScheduler.advanceUntilIdle()
|
||||
advanceTimeBy(TICK_MILLIS)
|
||||
testScheduler.advanceUntilIdle()
|
||||
|
||||
val emissions = deferred.await()
|
||||
assertThat(emissions).hasSize(2)
|
||||
|
||||
val apyFraction = apy.divide(BigDecimal("100"), 18, RoundingMode.HALF_UP)
|
||||
val perTickCrypto = amount.multiply(apyFraction)
|
||||
.multiply(YieldSupplyGetRewardsBalanceUseCase.TICK_SECONDS_BD)
|
||||
.divide(
|
||||
YieldSupplyGetRewardsBalanceUseCase.SECONDS_PER_YEAR_BD,
|
||||
YieldSupplyGetRewardsBalanceUseCase.SCALE,
|
||||
RoundingMode.HALF_UP,
|
||||
)
|
||||
.abs()
|
||||
val minCryptoDecimals = calculateMinVisibleDecimalsForTest(perTickCrypto).coerceAtMost(currency.decimals)
|
||||
|
||||
val fiatAmountStart = amount.multiply(fiatRate)
|
||||
val perTickFiat = fiatAmountStart.multiply(apyFraction)
|
||||
.multiply(YieldSupplyGetRewardsBalanceUseCase.TICK_SECONDS_BD)
|
||||
.divide(
|
||||
YieldSupplyGetRewardsBalanceUseCase.SECONDS_PER_YEAR_BD,
|
||||
YieldSupplyGetRewardsBalanceUseCase.SCALE,
|
||||
RoundingMode.HALF_UP,
|
||||
)
|
||||
.abs()
|
||||
val minFiatDecimals = calculateMinVisibleDecimalsForTest(perTickFiat)
|
||||
|
||||
val expectedCrypto0 = amount.format {
|
||||
crypto(currency).anyDecimals(
|
||||
maxDecimals = minCryptoDecimals,
|
||||
minDecimals = minCryptoDecimals,
|
||||
)
|
||||
}
|
||||
val expectedFiat0 = fiatAmountStart.format {
|
||||
fiat(appCurrency.code, appCurrency.symbol).anyDecimals(decimals = minFiatDecimals)
|
||||
}
|
||||
|
||||
assertThat(emissions[0].cryptoBalance).isEqualTo(expectedCrypto0)
|
||||
assertThat(emissions[0].fiatBalance).isEqualTo(expectedFiat0)
|
||||
}
|
||||
|
||||
private fun testDispatcherProvider(scope: TestScope): CoroutineDispatcherProvider {
|
||||
|
|
@ -260,42 +383,48 @@ class YieldSupplyGetRewardsBalanceUseCaseTest {
|
|||
}
|
||||
|
||||
private fun initialPerTickDelta(amount: BigDecimal, apy: BigDecimal): BigDecimal {
|
||||
val apyFraction = apy.divide(HUNDRED_BD, SCALE, RoundingMode.HALF_UP)
|
||||
val apyFraction = apy.divide(
|
||||
YieldSupplyGetRewardsBalanceUseCase.HUNDRED_BD,
|
||||
YieldSupplyGetRewardsBalanceUseCase.SCALE,
|
||||
RoundingMode.HALF_UP,
|
||||
)
|
||||
return amount
|
||||
.multiply(apyFraction)
|
||||
.multiply(TICK_SECONDS_BD)
|
||||
.divide(SECONDS_PER_YEAR_BD, SCALE, RoundingMode.HALF_UP)
|
||||
.multiply(YieldSupplyGetRewardsBalanceUseCase.TICK_SECONDS_BD)
|
||||
.divide(
|
||||
YieldSupplyGetRewardsBalanceUseCase.SECONDS_PER_YEAR_BD,
|
||||
YieldSupplyGetRewardsBalanceUseCase.SCALE,
|
||||
RoundingMode.HALF_UP,
|
||||
)
|
||||
.abs()
|
||||
}
|
||||
|
||||
private fun nextBalance(current: BigDecimal, apy: BigDecimal): BigDecimal {
|
||||
val apyFraction = apy.divide(HUNDRED_BD, SCALE, RoundingMode.HALF_UP)
|
||||
val apyFraction = apy.divide(
|
||||
YieldSupplyGetRewardsBalanceUseCase.HUNDRED_BD,
|
||||
YieldSupplyGetRewardsBalanceUseCase.SCALE,
|
||||
RoundingMode.HALF_UP,
|
||||
)
|
||||
val perTickDelta = current
|
||||
.multiply(apyFraction)
|
||||
.multiply(TICK_SECONDS_BD)
|
||||
.divide(SECONDS_PER_YEAR_BD, SCALE, RoundingMode.HALF_UP)
|
||||
.multiply(YieldSupplyGetRewardsBalanceUseCase.TICK_SECONDS_BD)
|
||||
.divide(
|
||||
YieldSupplyGetRewardsBalanceUseCase.SECONDS_PER_YEAR_BD,
|
||||
YieldSupplyGetRewardsBalanceUseCase.SCALE,
|
||||
RoundingMode.HALF_UP,
|
||||
)
|
||||
return current.add(perTickDelta)
|
||||
}
|
||||
|
||||
private fun calculateMinVisibleDecimalsForTest(perTickDeltaAbs: BigDecimal): Int {
|
||||
if (perTickDeltaAbs <= BigDecimal.ZERO) return MIN_DECIMALS
|
||||
if (perTickDeltaAbs <= BigDecimal.ZERO) return YieldSupplyGetRewardsBalanceUseCase.MIN_DECIMALS
|
||||
val perTickAsDouble = perTickDeltaAbs.toDouble()
|
||||
if (perTickAsDouble.isNaN() || perTickAsDouble.isInfinite()) return MIN_DECIMALS
|
||||
val safe = if (perTickAsDouble <= 0.0) EPSILON else perTickAsDouble
|
||||
val raw = ceil(-ln(safe) / LN_10)
|
||||
return raw.toInt().coerceIn(MIN_DECIMALS, MAX_DECIMALS)
|
||||
}
|
||||
|
||||
private companion object {
|
||||
private const val SCALE = 18
|
||||
private val TICK_SECONDS_BD = BigDecimal("0.3")
|
||||
private val SECONDS_PER_YEAR_BD = BigDecimal("31536000")
|
||||
private val HUNDRED_BD = BigDecimal("100")
|
||||
|
||||
private const val MIN_DECIMALS = 3
|
||||
private const val MAX_DECIMALS = 8
|
||||
|
||||
private val LN_10 = ln(10.0)
|
||||
private const val EPSILON = 1e-18
|
||||
if (perTickAsDouble.isNaN() || perTickAsDouble.isInfinite()) return YieldSupplyGetRewardsBalanceUseCase.MIN_DECIMALS
|
||||
val safe = if (perTickAsDouble <= 0.0) YieldSupplyGetRewardsBalanceUseCase.EPSILON else perTickAsDouble
|
||||
val raw = ceil(-kotlin.math.ln(safe) / YieldSupplyGetRewardsBalanceUseCase.LN_10)
|
||||
return raw.toInt().coerceIn(
|
||||
YieldSupplyGetRewardsBalanceUseCase.MIN_DECIMALS,
|
||||
YieldSupplyGetRewardsBalanceUseCase.FIAT_MAX_DECIMALS,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -19,7 +19,7 @@ internal class OnrampOffersStateFactory(
|
|||
return when (currentState) {
|
||||
is OnrampV2MainComponentUM.InitialLoading -> currentState
|
||||
is OnrampV2MainComponentUM.Content -> {
|
||||
if (currentState.offersBlockState is OnrampOffersBlockUM.Loading && offers.isEmpty()) {
|
||||
if (currentState.offersBlockState is OnrampOffersBlockUM.Loading) {
|
||||
return currentState
|
||||
}
|
||||
currentState.copy(
|
||||
|
|
|
|||
|
|
@ -64,7 +64,11 @@ internal class OnrampV2AmountStateFactory(
|
|||
currencySymbol = currency.unit,
|
||||
onAmountValueChanged = onrampIntents::onAmountValueChanged,
|
||||
),
|
||||
offersBlockState = OnrampOffersBlockUM.Loading,
|
||||
offersBlockState = if (amountState.amountFieldModel.fiatValue.isEmpty()) {
|
||||
OnrampOffersBlockUM.Empty
|
||||
} else {
|
||||
OnrampOffersBlockUM.Loading
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -98,6 +102,7 @@ internal class OnrampV2AmountStateFactory(
|
|||
amountBlockState = amountState.copy(secondaryFieldModel = OnrampSecondaryFieldErrorUM.Empty),
|
||||
onrampAmountButtonUMState = OnrampV2AmountButtonUMState.None,
|
||||
errorNotification = null,
|
||||
offersBlockState = currentState.offersBlockState,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -236,8 +236,17 @@ internal class OnrampV2MainComponentModel @Inject constructor(
|
|||
maybeOffers.fold(
|
||||
ifLeft = ::handleOnrampError,
|
||||
ifRight = { offers ->
|
||||
if (offers.isNotEmpty()) {
|
||||
state.update { onrampOffersStateFactory.getOffersState(offers) }
|
||||
val currentState = state.value
|
||||
if (currentState is OnrampV2MainComponentUM.Content) {
|
||||
if (currentState.amountBlockState.amountFieldModel.fiatValue.isEmpty()) {
|
||||
state.update {
|
||||
currentState.copy(offersBlockState = OnrampOffersBlockUM.Empty)
|
||||
}
|
||||
return@fold
|
||||
}
|
||||
state.update {
|
||||
onrampOffersStateFactory.getOffersState(offers)
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
|
|
@ -301,7 +310,17 @@ internal class OnrampV2MainComponentModel @Inject constructor(
|
|||
state.update { stateFactory.getErrorState(onRefresh = ::onRetryQuotes) }
|
||||
}
|
||||
else -> {
|
||||
state.update { amountStateFactory.getAmountSecondaryFieldResetState() }
|
||||
state.update { prevState ->
|
||||
val resetState = amountStateFactory.getAmountSecondaryFieldResetState()
|
||||
if (prevState is OnrampV2MainComponentUM.Content &&
|
||||
resetState is OnrampV2MainComponentUM.Content &&
|
||||
prevState.offersBlockState is OnrampOffersBlockUM.Loading
|
||||
) {
|
||||
resetState.copy(offersBlockState = OnrampOffersBlockUM.Empty)
|
||||
} else {
|
||||
resetState
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1651,8 +1651,7 @@ internal class SwapModel @Inject constructor(
|
|||
|
||||
private fun onTangemPaySupportClick(txId: String?) {
|
||||
modelScope.launch {
|
||||
val metaInfo = getWalletMetaInfoUseCase(userWallet.walletId)
|
||||
.getOrElse { error("CardInfo must be not null") }
|
||||
val metaInfo = getWalletMetaInfoUseCase(userWallet.walletId).getOrNull() ?: return@launch
|
||||
val email = FeedbackEmailType.Visa.Withdrawal(
|
||||
walletMetaInfo = metaInfo,
|
||||
providerName = dataState.selectedProvider?.name.orEmpty(),
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ internal class TangemPayDetailsModel @Inject constructor(
|
|||
val bottomSheetNavigation: SlotNavigation<TangemPayDetailsNavigation> = SlotNavigation()
|
||||
|
||||
init {
|
||||
analytics.send(TangemPayAnalyticsEvents.MainScreenOpened())
|
||||
handleBalanceHiding()
|
||||
fetchAddToWalletBanner()
|
||||
fetchBalance()
|
||||
|
|
@ -212,6 +213,7 @@ internal class TangemPayDetailsModel @Inject constructor(
|
|||
}
|
||||
|
||||
override fun onClickAddFunds() {
|
||||
analytics.send(TangemPayAnalyticsEvents.AddFundsClicked())
|
||||
val currentBalance = balance
|
||||
val depositAddress = currentBalance?.depositAddress
|
||||
if (currentBalance == null || depositAddress == null) {
|
||||
|
|
|
|||
|
|
@ -9,8 +9,6 @@ import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
|
|||
import com.tangem.domain.feedback.GetWalletMetaInfoUseCase
|
||||
import com.tangem.domain.feedback.SendFeedbackEmailUseCase
|
||||
import com.tangem.domain.feedback.models.FeedbackEmailType
|
||||
import com.tangem.domain.models.wallet.requireColdWallet
|
||||
import com.tangem.domain.wallets.usecase.GetWalletsUseCase
|
||||
import com.tangem.features.tangempay.components.txHistory.TangemPayTxHistoryDetailsComponent
|
||||
import com.tangem.features.tangempay.entity.TangemPayTxHistoryDetailsUM
|
||||
import com.tangem.features.tangempay.model.transformers.TangemPayTxHistoryDetailsConverter
|
||||
|
|
@ -21,10 +19,8 @@ import javax.inject.Inject
|
|||
|
||||
@Stable
|
||||
@ModelScoped
|
||||
@Suppress("LongParameterList")
|
||||
internal class TangemPayTxHistoryDetailsModel @Inject constructor(
|
||||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
private val getUserWalletsUseCase: GetWalletsUseCase,
|
||||
private val getWalletMetaInfoUseCase: GetWalletMetaInfoUseCase,
|
||||
private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase,
|
||||
private val urlOpener: UrlOpener,
|
||||
|
|
@ -66,12 +62,7 @@ internal class TangemPayTxHistoryDetailsModel @Inject constructor(
|
|||
|
||||
private fun dispute() {
|
||||
modelScope.launch {
|
||||
val userWalletId = params.userWalletId
|
||||
val userWallet = getUserWalletsUseCase.invokeSync()
|
||||
.firstOrNull { it.walletId == userWalletId } ?: return@launch
|
||||
val walletMetaInfo = getWalletMetaInfoUseCase.invoke(
|
||||
userWallet.requireColdWallet().scanResponse,
|
||||
).getOrNull() ?: return@launch
|
||||
val walletMetaInfo = getWalletMetaInfoUseCase.invoke(params.userWalletId).getOrNull() ?: return@launch
|
||||
|
||||
sendFeedbackEmailUseCase.invoke(
|
||||
FeedbackEmailType.Visa.DisputeV2(
|
||||
|
|
|
|||
|
|
@ -234,7 +234,7 @@ internal object TangemPayTxHistoryDetailsConverter :
|
|||
)
|
||||
is TangemPayTxHistoryItem.Spend -> persistentListOf(
|
||||
ButtonState(
|
||||
text = resourceReference(R.string.tangem_pay_dispute),
|
||||
text = resourceReference(R.string.tangem_pay_get_help),
|
||||
onClick = this.onDisputeClick,
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -182,8 +182,7 @@ private fun TangemPayCardDetailsShownBlock(
|
|||
Row(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 16.dp)
|
||||
.fillMaxWidth()
|
||||
.weight(1f),
|
||||
.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
||||
) {
|
||||
CardDetailsTextContainer(
|
||||
|
|
@ -203,6 +202,7 @@ private fun TangemPayCardDetailsShownBlock(
|
|||
onCopy = onCopyCvv,
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
Row {
|
||||
SpacerWMax()
|
||||
TangemPayCardDetailsCustomButton(
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import androidx.compose.material3.Text
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Devices
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
|
|
@ -74,6 +75,7 @@ internal fun TangemPayTxHistoryDetailsContent(state: TangemPayTxHistoryDetailsUM
|
|||
text = state.transactionSubtitle.resolveReference(),
|
||||
style = TangemTheme.typography.body2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.padding(top = 8.dp),
|
||||
|
|
@ -84,7 +86,7 @@ internal fun TangemPayTxHistoryDetailsContent(state: TangemPayTxHistoryDetailsUM
|
|||
state.localTransactionText?.let { localTransaction ->
|
||||
Text(
|
||||
modifier = Modifier.padding(top = 4.dp),
|
||||
text = localTransaction,
|
||||
text = localTransaction.orMaskWithStars(state.isBalanceHidden),
|
||||
style = TangemTheme.typography.body2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
|
|
@ -207,11 +209,11 @@ private class TangemPayTxHistoryDetailsUMProvider : CollectionPreviewParameterPr
|
|||
dismiss = {},
|
||||
),
|
||||
TangemPayTxHistoryDetailsUM(
|
||||
isBalanceHidden = false,
|
||||
isBalanceHidden = true,
|
||||
title = stringReference("12 June • 12:40"),
|
||||
iconState = ImageReference.Res(R.drawable.ic_category_24),
|
||||
transactionTitle = stringReference("Starbucks"),
|
||||
transactionSubtitle = stringReference("Food and drinks"),
|
||||
transactionSubtitle = stringReference("Food and drinks Food and drinks Food and drinks Food and drinks"),
|
||||
transactionAmount = "-$5.86",
|
||||
transactionAmountColor = themedColor { TangemTheme.colors.text.primary1 },
|
||||
localTransactionText = "€ 5.36",
|
||||
|
|
|
|||
|
|
@ -340,7 +340,9 @@ private fun AddressItem(
|
|||
onClick = onOpenQrCodeClick,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.padding(horizontal = 12.dp, vertical = 32.dp),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 12.dp, vertical = 32.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
CurrencyIcon(
|
||||
|
|
|
|||
|
|
@ -88,6 +88,7 @@ dependencies {
|
|||
implementation(projects.domain.wallets)
|
||||
implementation(projects.domain.wallets.models)
|
||||
implementation(projects.domain.yieldSupply)
|
||||
implementation(projects.domain.yieldSupply.models)
|
||||
|
||||
/** Temp dependency to swap domain */
|
||||
implementation(projects.features.swap.domain)
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ internal object TokenDetailsPreviewData {
|
|||
selectedBalanceType = BalanceType.ALL,
|
||||
onBalanceSelect = {},
|
||||
displayCryptoBalance = "966,96 XLM",
|
||||
displayYeildSupplyCryptoBalance = null,
|
||||
displayYieldSupplyFiatBalance = null,
|
||||
displayFiatBalance = "91,50$",
|
||||
isBalanceSelectorEnabled = true,
|
||||
isBalanceFlickering = false,
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ import com.tangem.domain.wallets.usecase.GetExploreUrlUseCase
|
|||
import com.tangem.domain.wallets.usecase.GetExtendedPublicKeyForCurrencyUseCase
|
||||
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
||||
import com.tangem.domain.wallets.usecase.NetworkHasDerivationUseCase
|
||||
import com.tangem.domain.yield.supply.models.YieldSupplyRewardBalance
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyGetRewardsBalanceUseCase
|
||||
import com.tangem.feature.tokendetails.deeplink.TokenDetailsDeepLinkActionListener
|
||||
import com.tangem.feature.tokendetails.presentation.router.InnerTokenDetailsRouter
|
||||
|
|
@ -416,7 +417,9 @@ internal class TokenDetailsModel @Inject constructor(
|
|||
.saveIn(yieldSupplyBalanceJobHolder)
|
||||
} else {
|
||||
yieldSupplyBalanceJobHolder.cancel()
|
||||
internalUiState.value = stateFactory.getStateWithUpdatedYieldSupplyDisplayBalance(null)
|
||||
internalUiState.value = stateFactory.getStateWithUpdatedYieldSupplyDisplayBalance(
|
||||
YieldSupplyRewardBalance.empty(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1261,14 +1264,8 @@ internal class TokenDetailsModel @Inject constructor(
|
|||
}
|
||||
|
||||
private fun handleNavigationParam() {
|
||||
when (val action = params.navigationAction) {
|
||||
is NavigationAction.Staking -> openStaking()
|
||||
is NavigationAction.YieldSupply -> if (action.isActive) {
|
||||
modelScope.launch(dispatchers.default) {
|
||||
fetchCurrencyStatusUseCase(userWalletId = userWalletId, id = cryptoCurrency.id)
|
||||
}
|
||||
}
|
||||
else -> Unit
|
||||
if (params.navigationAction is NavigationAction.Staking) {
|
||||
openStaking()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,8 @@ internal sealed class TokenDetailsBalanceBlockState {
|
|||
val isBalanceSelectorEnabled: Boolean,
|
||||
val isBalanceFlickering: Boolean,
|
||||
val yieldSupplyState: TokenDetailsYieldSupplyState = TokenDetailsYieldSupplyState.Empty,
|
||||
val displayYeildSupplyCryptoBalance: String? = null,
|
||||
val displayYieldSupplyFiatBalance: String? = null,
|
||||
val displayYieldSupplyCryptoBalance: String? = null,
|
||||
) : TokenDetailsBalanceBlockState()
|
||||
|
||||
data class Error(
|
||||
|
|
|
|||
|
|
@ -98,8 +98,8 @@ internal class TokenDetailsLoadedBalanceConverter(
|
|||
stakingCryptoAmount,
|
||||
currentState.selectedBalanceType,
|
||||
),
|
||||
displayYeildSupplyCryptoBalance = (currentState as? TokenDetailsBalanceBlockState.Content)
|
||||
?.displayYeildSupplyCryptoBalance,
|
||||
displayYieldSupplyFiatBalance = (currentState as? TokenDetailsBalanceBlockState.Content)
|
||||
?.displayYieldSupplyFiatBalance,
|
||||
balanceSegmentedButtonConfig = currentState.balanceSegmentedButtonConfig,
|
||||
onBalanceSelect = clickIntents::onBalanceSelect,
|
||||
selectedBalanceType = currentState.selectedBalanceType,
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import com.tangem.domain.tokens.model.TokenActionsState
|
|||
import com.tangem.domain.tokens.model.warnings.CryptoCurrencyWarning
|
||||
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
||||
import com.tangem.domain.wallets.usecase.NetworkHasDerivationUseCase
|
||||
import com.tangem.domain.yield.supply.models.YieldSupplyRewardBalance
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.model.TokenDetailsClickIntents
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenBalanceSegmentedButtonConfig
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsAppBarMenuConfig
|
||||
|
|
@ -315,13 +316,18 @@ internal class TokenDetailsStateFactory(
|
|||
return balanceSelectStateConverter.convert(buttonConfig)
|
||||
}
|
||||
|
||||
fun getStateWithUpdatedYieldSupplyDisplayBalance(displayBalance: String?): TokenDetailsState {
|
||||
fun getStateWithUpdatedYieldSupplyDisplayBalance(
|
||||
yieldSupplyRewardBalance: YieldSupplyRewardBalance,
|
||||
): TokenDetailsState {
|
||||
val state = currentStateProvider()
|
||||
val balanceState = state.tokenBalanceBlockState
|
||||
return state.copy(
|
||||
tokenBalanceBlockState = when (balanceState) {
|
||||
is TokenDetailsBalanceBlockState.Content ->
|
||||
balanceState.copy(displayYeildSupplyCryptoBalance = displayBalance)
|
||||
balanceState.copy(
|
||||
displayYieldSupplyFiatBalance = yieldSupplyRewardBalance.fiatBalance,
|
||||
displayYieldSupplyCryptoBalance = yieldSupplyRewardBalance.cryptoBalance,
|
||||
)
|
||||
is TokenDetailsBalanceBlockState.Error -> balanceState
|
||||
is TokenDetailsBalanceBlockState.Loading -> balanceState
|
||||
},
|
||||
|
|
|
|||
|
|
@ -122,12 +122,12 @@ private fun FiatBalance(
|
|||
height = TangemTheme.dimens.size32,
|
||||
),
|
||||
)
|
||||
is TokenDetailsBalanceBlockState.Content -> if (state.displayYeildSupplyCryptoBalance != null &&
|
||||
is TokenDetailsBalanceBlockState.Content -> if (state.displayYieldSupplyFiatBalance != null &&
|
||||
!isBalanceHidden
|
||||
) {
|
||||
TextAnimatedCounter(
|
||||
modifier = modifier,
|
||||
text = state.displayYeildSupplyCryptoBalance,
|
||||
text = state.displayYieldSupplyFiatBalance,
|
||||
style = TangemTheme.typography.h2.applyBladeBrush(
|
||||
isEnabled = state.isBalanceFlickering,
|
||||
textColor = TangemTheme.colors.text.primary1,
|
||||
|
|
@ -136,7 +136,7 @@ private fun FiatBalance(
|
|||
} else {
|
||||
Text(
|
||||
modifier = modifier,
|
||||
text = (state.displayYeildSupplyCryptoBalance ?: state.displayFiatBalance).orMaskWithStars(
|
||||
text = (state.displayYieldSupplyFiatBalance ?: state.displayFiatBalance).orMaskWithStars(
|
||||
isBalanceHidden,
|
||||
),
|
||||
style = TangemTheme.typography.h2.applyBladeBrush(
|
||||
|
|
@ -184,8 +184,9 @@ private fun CryptoBalance(
|
|||
tint = TangemTheme.colors.icon.inactive,
|
||||
contentDescription = null,
|
||||
)
|
||||
Text(
|
||||
text = state.displayCryptoBalance.orMaskWithStars(isBalanceHidden),
|
||||
TextAnimatedCounter(
|
||||
text = (state.displayYieldSupplyCryptoBalance ?: state.displayCryptoBalance)
|
||||
.orMaskWithStars(isBalanceHidden),
|
||||
style = TangemTheme.typography.caption2.applyBladeBrush(
|
||||
isEnabled = state.isBalanceFlickering,
|
||||
textColor = TangemTheme.colors.text.tertiary,
|
||||
|
|
|
|||
|
|
@ -41,7 +41,9 @@ internal class TxHistoryItemToTransactionStateConverter(
|
|||
R.drawable.ic_close_24
|
||||
} else {
|
||||
when (type) {
|
||||
is TransactionType.Approve -> R.drawable.ic_doc_24
|
||||
is TransactionType.YieldSupply.DeployContract,
|
||||
is TransactionType.Approve,
|
||||
-> R.drawable.ic_doc_24
|
||||
is TransactionType.Staking.Stake,
|
||||
is TransactionType.Staking.Vote,
|
||||
is TransactionType.Staking.Restake,
|
||||
|
|
@ -51,11 +53,16 @@ internal class TxHistoryItemToTransactionStateConverter(
|
|||
is TransactionType.Staking.Unstake,
|
||||
is TransactionType.Staking.Withdraw,
|
||||
-> R.drawable.ic_transaction_history_unstaking_24
|
||||
is TransactionType.YieldSupply.Enter -> R.drawable.ic_connect_24
|
||||
is TransactionType.YieldSupply.InitializeToken -> R.drawable.ic_gear_24
|
||||
is TransactionType.YieldSupply.ReactivateToken -> R.drawable.ic_refresh_24
|
||||
is TransactionType.YieldSupply.Exit -> R.drawable.ic_disconnect_24
|
||||
is TransactionType.Operation,
|
||||
is TransactionType.Swap,
|
||||
is TransactionType.Transfer,
|
||||
is TransactionType.YieldSupply,
|
||||
is TransactionType.UnknownOperation,
|
||||
TransactionType.YieldSupply.Send,
|
||||
TransactionType.YieldSupply.Topup,
|
||||
-> if (isOutgoing) R.drawable.ic_arrow_up_24 else R.drawable.ic_arrow_down_24
|
||||
}
|
||||
}
|
||||
|
|
@ -66,32 +73,76 @@ internal class TxHistoryItemToTransactionStateConverter(
|
|||
is TransactionType.Operation -> stringReference(type.name)
|
||||
is TransactionType.Swap -> resourceReference(R.string.common_swap)
|
||||
is TransactionType.Transfer -> resourceReference(R.string.common_transfer)
|
||||
is TransactionType.YieldSupply.Enter -> resourceReference(R.string.yield_module_transaction_enter)
|
||||
is TransactionType.YieldSupply.Exit -> resourceReference(R.string.yield_module_transaction_exit)
|
||||
is TransactionType.YieldSupply.Topup -> resourceReference(R.string.yield_module_transaction_topup)
|
||||
is TransactionType.Staking.Stake -> resourceReference(R.string.common_stake)
|
||||
is TransactionType.Staking.Unstake -> resourceReference(R.string.common_unstake)
|
||||
is TransactionType.Staking.Vote -> resourceReference(R.string.staking_vote)
|
||||
is TransactionType.Staking.ClaimRewards -> resourceReference(R.string.common_claim_rewards)
|
||||
is TransactionType.Staking.Withdraw -> resourceReference(R.string.staking_withdraw)
|
||||
is TransactionType.Staking.Restake -> resourceReference(R.string.staking_restake)
|
||||
is TransactionType.YieldSupply -> when (type) {
|
||||
is TransactionType.YieldSupply.Enter -> resourceReference(R.string.yield_module_transaction_enter)
|
||||
is TransactionType.YieldSupply.Exit -> resourceReference(R.string.yield_module_transaction_exit)
|
||||
TransactionType.YieldSupply.Topup -> resourceReference(R.string.yield_module_transaction_topup)
|
||||
TransactionType.YieldSupply.Send -> if (isOutgoing) {
|
||||
resourceReference(R.string.common_transfer)
|
||||
} else {
|
||||
resourceReference(R.string.yield_module_transaction_withdraw)
|
||||
}
|
||||
is TransactionType.YieldSupply.DeployContract -> resourceReference(
|
||||
R.string
|
||||
.yield_module_transaction_deploy_contract,
|
||||
)
|
||||
is TransactionType.YieldSupply.InitializeToken -> resourceReference(
|
||||
R.string
|
||||
.yield_module_transaction_initialize,
|
||||
)
|
||||
is TransactionType.YieldSupply.ReactivateToken -> resourceReference(
|
||||
R.string
|
||||
.yield_module_transaction_reactivate,
|
||||
)
|
||||
}
|
||||
is TransactionType.UnknownOperation -> resourceReference(R.string.transaction_history_operation)
|
||||
}
|
||||
|
||||
private fun TxInfo.extractSubtitle(): TextReference {
|
||||
return when (this.type) {
|
||||
is TransactionType.YieldSupply.Enter -> {
|
||||
val amount = amount.format { crypto(symbol = currency.symbol, decimals = currency.decimals) }
|
||||
resourceReference(R.string.yield_module_transaction_enter_subtitle, wrappedList(amount))
|
||||
}
|
||||
is TransactionType.YieldSupply.Topup,
|
||||
-> {
|
||||
val amount = amount.format { crypto(symbol = currency.symbol, decimals = currency.decimals) }
|
||||
resourceReference(R.string.yield_module_transaction_topup_subtitle, wrappedList(amount))
|
||||
}
|
||||
is TransactionType.YieldSupply.Exit -> {
|
||||
val amount = amount.format { crypto(symbol = currency.symbol, decimals = currency.decimals) }
|
||||
resourceReference(R.string.yield_module_transaction_exit_subtitle, wrappedList(amount))
|
||||
return when (val type = this.type) {
|
||||
is TransactionType.YieldSupply -> if (currency is CryptoCurrency.Coin) {
|
||||
if (type == TransactionType.YieldSupply.Send) {
|
||||
extractSubtitleByAddressType()
|
||||
} else {
|
||||
resourceReference(
|
||||
R.string.transaction_history_transaction_for_address,
|
||||
wrappedList(type.address?.toBriefAddressFormat().orEmpty()),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
when (type) {
|
||||
is TransactionType.YieldSupply.Enter -> {
|
||||
val amount = amount.format { crypto(symbol = currency.symbol, decimals = currency.decimals) }
|
||||
resourceReference(R.string.yield_module_transaction_enter_subtitle, wrappedList(amount))
|
||||
}
|
||||
TransactionType.YieldSupply.Topup -> {
|
||||
val amount = amount.format { crypto(symbol = currency.symbol, decimals = currency.decimals) }
|
||||
resourceReference(R.string.yield_module_transaction_topup_subtitle, wrappedList(amount))
|
||||
}
|
||||
is TransactionType.YieldSupply.Exit -> {
|
||||
val amount = amount.format { crypto(symbol = currency.symbol, decimals = currency.decimals) }
|
||||
resourceReference(R.string.yield_module_transaction_exit_subtitle, wrappedList(amount))
|
||||
}
|
||||
TransactionType.YieldSupply.Send -> {
|
||||
if (isOutgoing) {
|
||||
extractSubtitleByAddressType()
|
||||
} else {
|
||||
val amount =
|
||||
amount.format { crypto(symbol = currency.symbol, decimals = currency.decimals) }
|
||||
resourceReference(
|
||||
R.string.yield_module_transaction_exit_subtitle,
|
||||
wrappedList(amount),
|
||||
)
|
||||
}
|
||||
}
|
||||
else -> extractSubtitleByAddressType()
|
||||
}
|
||||
}
|
||||
else -> extractSubtitleByAddressType()
|
||||
}
|
||||
|
|
@ -133,14 +184,21 @@ internal class TxHistoryItemToTransactionStateConverter(
|
|||
|
||||
@Suppress("ComplexCondition")
|
||||
private fun TxInfo.getAmount(): String {
|
||||
if (type is TransactionType.Staking.Vote ||
|
||||
type == TransactionType.Staking.ClaimRewards ||
|
||||
type == TransactionType.Staking.Withdraw ||
|
||||
type == TransactionType.YieldSupply.Enter ||
|
||||
type == TransactionType.YieldSupply.Exit ||
|
||||
type == TransactionType.YieldSupply.Topup
|
||||
) {
|
||||
return ""
|
||||
when (type) {
|
||||
is TransactionType.Staking.Vote,
|
||||
TransactionType.Staking.ClaimRewards,
|
||||
TransactionType.Staking.Withdraw,
|
||||
-> return ""
|
||||
|
||||
is TransactionType.YieldSupply -> if (currency is CryptoCurrency.Token) {
|
||||
when (type) {
|
||||
TransactionType.YieldSupply.Send -> if (!isOutgoing) {
|
||||
return ""
|
||||
}
|
||||
else -> return ""
|
||||
}
|
||||
}
|
||||
else -> Unit
|
||||
}
|
||||
val prefix = when {
|
||||
status == TxInfo.TransactionStatus.Failed -> ""
|
||||
|
|
|
|||
|
|
@ -537,7 +537,7 @@ internal class WalletModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private suspend fun reinitializeWallet(action: WalletsUpdateActionResolver.Action.ReinitializeWallet) {
|
||||
private fun reinitializeWallet(action: WalletsUpdateActionResolver.Action.ReinitializeWallet) {
|
||||
walletScreenContentLoader.cancel(action.prevWalletId)
|
||||
tokenListStore.remove(action.prevWalletId)
|
||||
|
||||
|
|
@ -585,7 +585,7 @@ internal class WalletModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private suspend fun addWallet(action: WalletsUpdateActionResolver.Action.AddWallet) {
|
||||
private fun addWallet(action: WalletsUpdateActionResolver.Action.AddWallet) {
|
||||
if (accountsFeatureToggles.isFeatureEnabled) {
|
||||
fetchWalletContent(userWallet = action.selectedWallet)
|
||||
|
||||
|
|
@ -725,15 +725,15 @@ internal class WalletModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private suspend fun fetchWalletContent(userWallet: UserWallet) {
|
||||
private fun fetchWalletContent(userWallet: UserWallet) {
|
||||
if (userWallet.isLocked) return
|
||||
|
||||
/*
|
||||
* Updating the balance of the current wallet is an essential part of InitializationWallets,
|
||||
* so the coroutine is launched in the current context
|
||||
*/
|
||||
supervisorScope {
|
||||
launch { walletContentFetcher(userWalletId = userWallet.walletId) }
|
||||
modelScope.launch {
|
||||
walletContentFetcher(userWalletId = userWallet.walletId)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,11 +10,9 @@ import com.tangem.domain.feedback.GetWalletMetaInfoUseCase
|
|||
import com.tangem.domain.feedback.SendFeedbackEmailUseCase
|
||||
import com.tangem.domain.feedback.models.FeedbackEmailType
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.models.wallet.requireColdWallet
|
||||
import com.tangem.domain.pay.repository.OnboardingRepository
|
||||
import com.tangem.domain.pay.usecase.ProduceTangemPayInitialDataUseCase
|
||||
import com.tangem.domain.pay.usecase.TangemPayMainScreenCustomerInfoUseCase
|
||||
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController
|
||||
import com.tangem.features.tangempay.TangemPayFeatureToggles
|
||||
import kotlinx.coroutines.launch
|
||||
|
|
@ -41,7 +39,6 @@ internal class TangemPayClickIntentsImplementor @Inject constructor(
|
|||
private val onboardingRepository: OnboardingRepository,
|
||||
private val produceInitialDataTangemPay: ProduceTangemPayInitialDataUseCase,
|
||||
private val getWalletMetainfoUseCase: GetWalletMetaInfoUseCase,
|
||||
private val getUserWalletUseCase: GetUserWalletUseCase,
|
||||
private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase,
|
||||
private val tangemPayMainScreenCustomerInfoUseCase: TangemPayMainScreenCustomerInfoUseCase,
|
||||
private val uiMessageSender: UiMessageSender,
|
||||
|
|
@ -68,6 +65,7 @@ internal class TangemPayClickIntentsImplementor @Inject constructor(
|
|||
val issuingBottomSheet = bottomSheetMessage {
|
||||
infoBlock {
|
||||
icon(com.tangem.core.ui.R.drawable.ic_clock_24) {
|
||||
type = MessageBottomSheetUMV2.Icon.Type.Informative
|
||||
backgroundType = MessageBottomSheetUMV2.Icon.BackgroundType.Informative
|
||||
}
|
||||
title = resourceReference(R.string.tangempay_issuing_your_card)
|
||||
|
|
@ -93,7 +91,7 @@ internal class TangemPayClickIntentsImplementor @Inject constructor(
|
|||
body = resourceReference(R.string.tangempay_failed_to_issue_card_support_description)
|
||||
}
|
||||
secondaryButton {
|
||||
text = resourceReference(R.string.common_contact_support)
|
||||
text = resourceReference(R.string.tangempay_go_to_support)
|
||||
onClick {
|
||||
onPaySupportClick()
|
||||
closeBs()
|
||||
|
|
@ -106,10 +104,8 @@ internal class TangemPayClickIntentsImplementor @Inject constructor(
|
|||
|
||||
override fun onPaySupportClick() {
|
||||
modelScope.launch {
|
||||
val userWalletId = stateHolder.getSelectedWalletId()
|
||||
val userWallet = getUserWalletUseCase.invoke(userWalletId).getOrNull() ?: return@launch
|
||||
val cardInfo = getWalletMetainfoUseCase.invoke(
|
||||
userWallet.requireColdWallet().scanResponse,
|
||||
userWalletId = stateHolder.getSelectedWalletId(),
|
||||
).getOrNull() ?: return@launch
|
||||
|
||||
sendFeedbackEmailUseCase(
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import com.tangem.domain.tokens.model.details.NavigationAction
|
|||
import com.tangem.domain.txhistory.usecase.GetExplorerTransactionUrlUseCase
|
||||
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyEnterStatusUseCase
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplySetShouldShowMainPromoUseCase
|
||||
import com.tangem.feature.wallet.presentation.account.AccountDependencies
|
||||
import com.tangem.feature.wallet.presentation.wallet.domain.OnrampStatusFactory
|
||||
import com.tangem.feature.wallet.presentation.wallet.domain.unwrap
|
||||
|
|
@ -58,6 +59,8 @@ internal interface WalletContentClickIntents {
|
|||
apy: String,
|
||||
)
|
||||
|
||||
fun onYieldPromoCloseClick()
|
||||
|
||||
fun onAccountExpandClick(account: Account)
|
||||
|
||||
fun onAccountCollapseClick(account: Account)
|
||||
|
|
@ -95,6 +98,7 @@ internal class WalletContentClickIntentsImplementor @Inject constructor(
|
|||
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
private val accountDependencies: AccountDependencies,
|
||||
private val yieldSupplyEnterStatusUseCase: YieldSupplyEnterStatusUseCase,
|
||||
private val yieldSupplySetShouldShowMainPromoUseCase: YieldSupplySetShouldShowMainPromoUseCase,
|
||||
) : BaseWalletClickIntents(), WalletContentClickIntents {
|
||||
|
||||
override fun onDetailsClick() {
|
||||
|
|
@ -194,6 +198,12 @@ internal class WalletContentClickIntentsImplementor @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override fun onYieldPromoCloseClick() {
|
||||
modelScope.launch {
|
||||
yieldSupplySetShouldShowMainPromoUseCase(false)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onAccountExpandClick(account: Account) {
|
||||
val userWalletId = stateHolder.getSelectedWalletId()
|
||||
analyticsEventHandler.send(MainScreenAnalyticsEvent.AccountShowTokens())
|
||||
|
|
|
|||
|
|
@ -317,6 +317,11 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor(
|
|||
program = Program.BlackFriday,
|
||||
action = PromotionBannerClicked.BannerAction.Closed(),
|
||||
)
|
||||
PromoId.OnePlusOne -> PromotionBannerClicked(
|
||||
source = AnalyticsParam.ScreensSources.Main,
|
||||
program = Program.OnePlusOne,
|
||||
action = PromotionBannerClicked.BannerAction.Closed(),
|
||||
)
|
||||
},
|
||||
|
||||
)
|
||||
|
|
@ -364,6 +369,16 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor(
|
|||
)
|
||||
urlOpener.openUrl(BLACK_FRIDAY_PROMO_LINK)
|
||||
}
|
||||
PromoId.OnePlusOne -> {
|
||||
analyticsEventHandler.send(
|
||||
PromotionBannerClicked(
|
||||
source = AnalyticsParam.ScreensSources.Main,
|
||||
program = Program.OnePlusOne,
|
||||
action = PromotionBannerClicked.BannerAction.Clicked(),
|
||||
),
|
||||
)
|
||||
urlOpener.openUrl(ONE_PLUS_ONE_PROMO_LINK)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -581,5 +596,10 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor(
|
|||
"&utm_source=tangem-app-banner" +
|
||||
"&utm_medium=banner" +
|
||||
"&utm_campaign=BlackFriday2025"
|
||||
const val ONE_PLUS_ONE_PROMO_LINK = "https://tangem.com/pricing/" +
|
||||
"?cat=family" +
|
||||
"&utm_source=tangem-app-banner" +
|
||||
"&utm_medium=banner" +
|
||||
"&utm_campaign=BOGO50"
|
||||
}
|
||||
}
|
||||
|
|
@ -27,7 +27,7 @@ internal class WalletTangemPayAnalyticsEventSender @Inject constructor(
|
|||
val event = when {
|
||||
customerInfo.orderStatus == OrderStatus.CANCELED -> return // ignore cancelled state on analytics
|
||||
!customerInfo.info.isKycApproved -> return // ignore kyc not approved state on analytics
|
||||
cardInfo != null && productInstance != null -> TangemPayAnalyticsEvents.MainScreenOpened()
|
||||
cardInfo != null && productInstance != null -> return
|
||||
else -> TangemPayAnalyticsEvents.IssuingBannerDisplayed()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -62,6 +62,10 @@ internal class WalletWarningsAnalyticsSender @Inject constructor(
|
|||
source = AnalyticsParam.ScreensSources.Main,
|
||||
program = Program.BlackFriday,
|
||||
)
|
||||
is WalletNotification.OnePlusOnePromo -> NoticePromotionBanner(
|
||||
source = AnalyticsParam.ScreensSources.Main,
|
||||
program = Program.OnePlusOne,
|
||||
)
|
||||
is WalletNotification.ReferralPromo -> MainScreen.ReferralPromo()
|
||||
is WalletNotification.VisaPresalePromo -> VisaWaitlistPromo()
|
||||
is WalletNotification.UnlockWallets -> null // See [SelectedWalletAnalyticsSender]
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
package com.tangem.feature.wallet.presentation.wallet.domain
|
||||
|
||||
import arrow.core.getOrElse
|
||||
import com.tangem.common.ui.notifications.NotificationId
|
||||
import com.tangem.common.ui.userwallet.ext.walletInterationIcon
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
|
|
@ -21,12 +20,9 @@ import com.tangem.domain.models.currency.CryptoCurrency
|
|||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.notifications.repository.NotificationsRepository
|
||||
import com.tangem.domain.onramp.GetOnrampCountryUseCase
|
||||
import com.tangem.domain.onramp.OnrampSepaAvailableUseCase
|
||||
import com.tangem.domain.promo.ShouldShowPromoWalletUseCase
|
||||
import com.tangem.domain.promo.models.PromoId
|
||||
import com.tangem.domain.settings.IsReadyToShowRateAppUseCase
|
||||
import com.tangem.domain.tokens.GetCryptoCurrenciesUseCase
|
||||
import com.tangem.domain.tokens.error.TokenListError
|
||||
import com.tangem.domain.wallets.models.SeedPhraseNotificationsStatus
|
||||
import com.tangem.domain.wallets.usecase.IsNeedToBackupUseCase
|
||||
|
|
@ -37,7 +33,6 @@ import com.tangem.feature.wallet.impl.R
|
|||
import com.tangem.feature.wallet.presentation.account.AccountDependencies
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletNotification
|
||||
import com.tangem.hot.sdk.model.HotWalletId
|
||||
import com.tangem.lib.crypto.BlockchainUtils.isBitcoin
|
||||
import com.tangem.utils.extensions.addIf
|
||||
import com.tangem.utils.extensions.isPositive
|
||||
import com.tangem.utils.extensions.orZero
|
||||
|
|
@ -47,7 +42,6 @@ import kotlinx.coroutines.flow.Flow
|
|||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.map
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@Suppress("LongParameterList", "LargeClass")
|
||||
|
|
@ -60,9 +54,6 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
|
|||
private val backupValidator: BackupValidator,
|
||||
private val seedPhraseNotificationUseCase: SeedPhraseNotificationUseCase,
|
||||
private val shouldShowPromoWalletUseCase: ShouldShowPromoWalletUseCase,
|
||||
private val getCryptoCurrenciesUseCase: GetCryptoCurrenciesUseCase,
|
||||
private val onrampSepaAvailableUseCase: OnrampSepaAvailableUseCase,
|
||||
private val getOnrampCountryUseCase: GetOnrampCountryUseCase,
|
||||
private val notificationsRepository: NotificationsRepository,
|
||||
private val accountDependencies: AccountDependencies,
|
||||
private val getAccessCodeSkippedUseCase: GetAccessCodeSkippedUseCase,
|
||||
|
|
@ -99,11 +90,7 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
|
|||
isReadyToShowRateAppUseCase().distinctUntilChanged(),
|
||||
isNeedToBackupUseCase(userWallet.walletId).distinctUntilChanged(),
|
||||
seedPhraseNotificationUseCase(userWalletId = userWallet.walletId).distinctUntilChanged(),
|
||||
shouldShowPromoWalletUseCase(userWalletId = userWallet.walletId, promoId = PromoId.VisaPresale)
|
||||
.distinctUntilChanged(),
|
||||
shouldShowPromoWalletUseCase(userWalletId = userWallet.walletId, promoId = PromoId.Sepa)
|
||||
.distinctUntilChanged(),
|
||||
shouldShowPromoWalletUseCase(userWalletId = userWallet.walletId, promoId = PromoId.BlackFriday)
|
||||
shouldShowPromoWalletUseCase(userWalletId = userWallet.walletId, promoId = PromoId.OnePlusOne)
|
||||
.distinctUntilChanged(),
|
||||
notificationsRepository.getShouldShowNotification(NotificationId.EnablePushesReminderNotification.key)
|
||||
.distinctUntilChanged(),
|
||||
|
|
@ -117,11 +104,9 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
|
|||
val isReadyToShowRating = array[1] as Boolean
|
||||
val isNeedToBackup = array[2] as Boolean
|
||||
val seedPhraseIssueStatus = array[3] as SeedPhraseNotificationsStatus
|
||||
val shouldShowVisaPromo = array[4] as Boolean
|
||||
val shouldShowSepaBanner = array[5] as Boolean
|
||||
val shouldShowBlackFridayPromo = array[6] as Boolean
|
||||
val shouldShowEnablePushesReminderNotification = array[7] as Boolean
|
||||
val shouldAccessCodeSkipped = array[8] as Boolean
|
||||
val shouldShowOnePlusOnePromo = array[4] as Boolean
|
||||
val shouldShowEnablePushesReminderNotification = array[5] as Boolean
|
||||
val shouldAccessCodeSkipped = array[6] as Boolean
|
||||
|
||||
buildList {
|
||||
addUsedOutdatedDataNotification(totalFiatBalance)
|
||||
|
|
@ -135,16 +120,7 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
|
|||
shouldAccessCodeSkipped = shouldAccessCodeSkipped,
|
||||
)
|
||||
|
||||
addBlackFridayPromoNotification(clickIntents, shouldShowBlackFridayPromo)
|
||||
|
||||
addVisaPresalePromoNotification(clickIntents, shouldShowVisaPromo)
|
||||
|
||||
addSepaPromoNotification(
|
||||
userWallet = userWallet,
|
||||
flattenCurrencies = flattenCurrencies,
|
||||
clickIntents = clickIntents,
|
||||
shouldShowSepaPromo = shouldShowSepaBanner,
|
||||
)
|
||||
addOnePlusOnePromoNotification(clickIntents, shouldShowOnePlusOnePromo)
|
||||
|
||||
addInformationalNotifications(userWallet, cardTypesResolver, flattenCurrencies, clickIntents)
|
||||
|
||||
|
|
@ -297,72 +273,19 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
|
|||
.map(CryptoCurrencyStatus::currency)
|
||||
}
|
||||
|
||||
private fun MutableList<WalletNotification>.addVisaPresalePromoNotification(
|
||||
private fun MutableList<WalletNotification>.addOnePlusOnePromoNotification(
|
||||
clickIntents: WalletClickIntents,
|
||||
shouldShowPromo: Boolean,
|
||||
) {
|
||||
addIf(
|
||||
element = WalletNotification.VisaPresalePromo(
|
||||
onCloseClick = { clickIntents.onClosePromoClick(promoId = PromoId.VisaPresale) },
|
||||
onClick = { clickIntents.onPromoClick(promoId = PromoId.VisaPresale) },
|
||||
element = WalletNotification.OnePlusOnePromo(
|
||||
onCloseClick = { clickIntents.onClosePromoClick(promoId = PromoId.OnePlusOne) },
|
||||
onClick = { clickIntents.onPromoClick(promoId = PromoId.OnePlusOne) },
|
||||
),
|
||||
condition = shouldShowPromo,
|
||||
)
|
||||
}
|
||||
|
||||
private fun MutableList<WalletNotification>.addBlackFridayPromoNotification(
|
||||
clickIntents: WalletClickIntents,
|
||||
shouldShowPromo: Boolean,
|
||||
) {
|
||||
addIf(
|
||||
element = WalletNotification.BlackFridayPromo(
|
||||
onCloseClick = { clickIntents.onClosePromoClick(promoId = PromoId.BlackFriday) },
|
||||
onClick = { clickIntents.onPromoClick(promoId = PromoId.BlackFriday) },
|
||||
),
|
||||
condition = shouldShowPromo,
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun MutableList<WalletNotification>.addSepaPromoNotification(
|
||||
userWallet: UserWallet,
|
||||
flattenCurrencies: Lce<TokenListError, List<CryptoCurrencyStatus>>,
|
||||
clickIntents: WalletClickIntents,
|
||||
shouldShowSepaPromo: Boolean,
|
||||
) {
|
||||
val currencies = if (accountDependencies.accountsFeatureToggles.isFeatureEnabled) {
|
||||
flattenCurrencies.map { statuses -> statuses.map { it.currency } }.getOrNull() ?: run {
|
||||
Timber.e("Error on getting crypto currency list")
|
||||
return
|
||||
}
|
||||
} else {
|
||||
getCryptoCurrenciesUseCase(userWalletId = userWallet.walletId).getOrElse {
|
||||
Timber.e("Error on getting crypto currency list")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
val bitcoinCurrency = currencies.find { isBitcoin(it.network.rawId) } ?: return
|
||||
|
||||
val country = getOnrampCountryUseCase.invokeSync(userWallet).getOrElse {
|
||||
Timber.e("Error on getting onramp country")
|
||||
return
|
||||
}
|
||||
|
||||
val isSepaAvailable = onrampSepaAvailableUseCase(
|
||||
userWallet = userWallet,
|
||||
country = country,
|
||||
cryptoCurrency = bitcoinCurrency,
|
||||
)
|
||||
|
||||
addIf(
|
||||
element = WalletNotification.Sepa(
|
||||
onCloseClick = { clickIntents.onClosePromoClick(promoId = PromoId.Sepa) },
|
||||
onClick = { clickIntents.onPromoClick(promoId = PromoId.Sepa, bitcoinCurrency) },
|
||||
),
|
||||
condition = shouldShowSepaPromo && isSepaAvailable,
|
||||
)
|
||||
}
|
||||
|
||||
// private fun MutableList<WalletNotification>.addYieldSupplyNotifications(
|
||||
// flattenCurrencies: Lce<TokenListError, List<CryptoCurrencyStatus>>,
|
||||
// ) {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import com.tangem.domain.tokens.repository.CurrenciesRepository
|
|||
import com.tangem.domain.wallets.repository.WalletsRepository
|
||||
import com.tangem.domain.wallets.usecase.ShouldSaveUserWalletsUseCase
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyApyFlowUseCase
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyGetShouldShowMainPromoUseCase
|
||||
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.utils.TokenListAnalyticsSender
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.utils.WalletWarningsAnalyticsSender
|
||||
|
|
@ -45,6 +46,7 @@ internal class MultiWalletContentLoader(
|
|||
private val currenciesRepository: CurrenciesRepository,
|
||||
private val yieldSupplyApyFlowUseCase: YieldSupplyApyFlowUseCase,
|
||||
private val stakingApyFlowUseCase: StakingApyFlowUseCase,
|
||||
private val yieldSupplyGetShouldShowMainPromoUseCase: YieldSupplyGetShouldShowMainPromoUseCase,
|
||||
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
private val tangemPayFeatureToggles: TangemPayFeatureToggles,
|
||||
private val tangemPayMainSubscriberFactory: TangemPayMainSubscriber.Factory,
|
||||
|
|
@ -63,6 +65,7 @@ internal class MultiWalletContentLoader(
|
|||
applyTokenListSortingUseCase = applyTokenListSortingUseCase,
|
||||
yieldSupplyApyFlowUseCase = yieldSupplyApyFlowUseCase,
|
||||
stakingApyFlowUseCase = stakingApyFlowUseCase,
|
||||
yieldSupplyGetShouldShowMainPromoUseCase = yieldSupplyGetShouldShowMainPromoUseCase,
|
||||
).let(::add)
|
||||
|
||||
WalletNFTListSubscriber(
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import com.tangem.domain.tokens.repository.CurrenciesRepository
|
|||
import com.tangem.domain.wallets.repository.WalletsRepository
|
||||
import com.tangem.domain.wallets.usecase.ShouldSaveUserWalletsUseCase
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyApyFlowUseCase
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyGetShouldShowMainPromoUseCase
|
||||
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.utils.TokenListAnalyticsSender
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.utils.WalletWarningsAnalyticsSender
|
||||
|
|
@ -44,6 +45,7 @@ internal class MultiWalletContentLoaderFactory @Inject constructor(
|
|||
private val currenciesRepository: CurrenciesRepository,
|
||||
private val yieldSupplyApyFlowUseCase: YieldSupplyApyFlowUseCase,
|
||||
private val stakingApyFlowUseCase: StakingApyFlowUseCase,
|
||||
private val yieldSupplyGetShouldShowMainPromoUseCase: YieldSupplyGetShouldShowMainPromoUseCase,
|
||||
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
private val tangemPayFeatureToggles: TangemPayFeatureToggles,
|
||||
private val tangemPayMainSubscriberFactory: TangemPayMainSubscriber.Factory,
|
||||
|
|
@ -72,6 +74,7 @@ internal class MultiWalletContentLoaderFactory @Inject constructor(
|
|||
hotWalletFeatureToggles = hotWalletFeatureToggles,
|
||||
tangemPayFeatureToggles = tangemPayFeatureToggles,
|
||||
tangemPayMainSubscriberFactory = tangemPayMainSubscriberFactory,
|
||||
yieldSupplyGetShouldShowMainPromoUseCase = yieldSupplyGetShouldShowMainPromoUseCase,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ import com.tangem.domain.promo.GetStoryContentUseCase
|
|||
import com.tangem.domain.staking.usecase.StakingApyFlowUseCase
|
||||
import com.tangem.domain.wallets.usecase.ShouldSaveUserWalletsUseCase
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyApyFlowUseCase
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyGetShouldShowMainPromoUseCase
|
||||
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.utils.TokenListAnalyticsSender
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.utils.WalletWarningsAnalyticsSender
|
||||
|
|
@ -35,6 +36,7 @@ internal class SingleWalletWithTokenContentLoader(
|
|||
private val yieldSupplyApyFlowUseCase: YieldSupplyApyFlowUseCase,
|
||||
private val stakingApyFlowUseCase: StakingApyFlowUseCase,
|
||||
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
private val yieldSupplyGetShouldShowMainPromoUseCase: YieldSupplyGetShouldShowMainPromoUseCase,
|
||||
) : WalletContentLoader(id = userWallet.walletId) {
|
||||
|
||||
override fun create(): List<WalletSubscriber> {
|
||||
|
|
@ -49,6 +51,7 @@ internal class SingleWalletWithTokenContentLoader(
|
|||
getSelectedAppCurrencyUseCase = getSelectedAppCurrencyUseCase,
|
||||
yieldSupplyApyFlowUseCase = yieldSupplyApyFlowUseCase,
|
||||
stakingApyFlowUseCase = stakingApyFlowUseCase,
|
||||
yieldSupplyGetShouldShowMainPromoUseCase = yieldSupplyGetShouldShowMainPromoUseCase,
|
||||
).let(::add)
|
||||
MultiWalletWarningsSubscriber(
|
||||
userWallet = userWallet,
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import com.tangem.domain.promo.GetStoryContentUseCase
|
|||
import com.tangem.domain.staking.usecase.StakingApyFlowUseCase
|
||||
import com.tangem.domain.wallets.usecase.ShouldSaveUserWalletsUseCase
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyApyFlowUseCase
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyGetShouldShowMainPromoUseCase
|
||||
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.utils.TokenListAnalyticsSender
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.utils.WalletWarningsAnalyticsSender
|
||||
|
|
@ -36,6 +37,7 @@ internal class SingleWalletWithTokenContentLoaderFactory @Inject constructor(
|
|||
private val yieldSupplyApyFlowUseCase: YieldSupplyApyFlowUseCase,
|
||||
private val stakingApyFlowUseCase: StakingApyFlowUseCase,
|
||||
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
private val yieldSupplyGetShouldShowMainPromoUseCase: YieldSupplyGetShouldShowMainPromoUseCase,
|
||||
) {
|
||||
|
||||
fun create(userWallet: UserWallet.Cold, clickIntents: WalletClickIntents): SingleWalletWithTokenContentLoader {
|
||||
|
|
@ -55,6 +57,7 @@ internal class SingleWalletWithTokenContentLoaderFactory @Inject constructor(
|
|||
yieldSupplyApyFlowUseCase = yieldSupplyApyFlowUseCase,
|
||||
stakingApyFlowUseCase = stakingApyFlowUseCase,
|
||||
hotWalletFeatureToggles = hotWalletFeatureToggles,
|
||||
yieldSupplyGetShouldShowMainPromoUseCase = yieldSupplyGetShouldShowMainPromoUseCase,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -376,6 +376,23 @@ sealed class WalletNotification(val config: NotificationConfig) {
|
|||
),
|
||||
)
|
||||
|
||||
data class OnePlusOnePromo(
|
||||
val onCloseClick: () -> Unit,
|
||||
val onClick: () -> Unit,
|
||||
) : WalletNotification(
|
||||
config = NotificationConfig(
|
||||
title = resourceReference(R.string.notification_one_plus_one_title),
|
||||
subtitle = resourceReference(R.string.notification_one_plus_one_text),
|
||||
iconResId = R.drawable.img_one_plus_one_promo,
|
||||
onCloseClick = onCloseClick,
|
||||
buttonsState = NotificationConfig.ButtonsState.SecondaryButtonConfig(
|
||||
text = resourceReference(R.string.notification_one_plus_one_button),
|
||||
onClick = onClick,
|
||||
),
|
||||
iconSize = 54.dp,
|
||||
),
|
||||
)
|
||||
|
||||
data class PushNotifications(
|
||||
val onCloseClick: () -> Unit,
|
||||
val onEnabledClick: () -> Unit,
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue