Updated on 2026-08-14

This commit is contained in:
Tangem 2025-02-03 13:23:27 +03:00
commit cc9ccd9648
54 changed files with 532 additions and 289 deletions

View file

@ -14,6 +14,7 @@
</value>
</option>
<option name="LINE_BREAK_AFTER_MULTILINE_WHEN_ENTRY" value="false" />
<option name="INDENT_BEFORE_ARROW_ON_NEW_LINE" value="false" />
<option name="NAME_COUNT_TO_USE_STAR_IMPORT" value="5" />
<option name="NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS" value="3" />
<option name="ALLOW_TRAILING_COMMA" value="true" />

View file

@ -13,7 +13,6 @@ sealed class Onboarding(
class Started : Onboarding("Onboarding", "Onboarding Started")
class Finished : Onboarding("Onboarding", "Onboarding Finished")
data object OfflineAttestationFailed : Onboarding(category = "Onboarding", event = "Offline Attestation Failed")
sealed class CreateWallet(
event: String,

View file

@ -38,7 +38,7 @@ internal class TangemPushNotificationService : FirebaseMessagingService() {
// TODO refactoring: [REDACTED_JIRA]
val intent = Intent(applicationContext, MainActivity::class.java)
intent.putExtra(OnPushClickedIntentHandler.IS_OPENED_FROM_PUSH, true)
intent.putExtra(OnPushClickedIntentHandler.OPENED_FROM_GCM_PUSH, true)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
val pendingIntent = PendingIntent.getActivity(
/* context = */ this,

View file

@ -67,7 +67,7 @@ internal class AddressInfoBottomSheetDialog(
val blockchain = stateDialog.currency.blockchain
tvReceiveMessage.text = tvReceiveMessage.getString(
id = R.string.address_qr_code_message_format,
blockchain.fullName,
blockchain.getCoinName(),
blockchain.currency,
blockchain.fullName,
)

View file

@ -19,11 +19,13 @@ internal class DefaultScanCardProcessor(
override suspend fun scan(
cardId: String?,
allowsRequestAccessCodeFromRepository: Boolean,
analyticsSource: AnalyticsParam.ScreensSources,
): CompletionResult<ScanResponse> {
return if (isNewCardScanningEnabled) {
UseCaseScanProcessor.scan(cardId, allowsRequestAccessCodeFromRepository)
} else {
legacyScanProcessor.scan(
analyticsSource = analyticsSource,
cardId = cardId,
allowsRequestAccessCodeFromRepository = allowsRequestAccessCodeFromRepository,
)

View file

@ -59,13 +59,14 @@ internal class LegacyScanProcessor @Inject constructor(
suspend fun scan(
cardId: String? = null,
allowsRequestAccessCodeFromRepository: Boolean = false,
analyticsSource: AnalyticsParam.ScreensSources,
): CompletionResult<ScanResponse> {
return tangemSdkManager.scanProduct(
cardId = cardId,
allowsRequestAccessCodeFromRepository = allowsRequestAccessCodeFromRepository,
)
.doOnFailure { error ->
onScanFailure(error = error, onFailure = {}, onCancel = {})
onScanFailure(analyticsSource = analyticsSource, error = error, onFailure = {}, onCancel = {})
}
}
@ -92,6 +93,7 @@ internal class LegacyScanProcessor @Inject constructor(
result
.doOnFailure { error ->
onScanFailure(
analyticsSource = analyticsSource,
error = error,
onFailure = onFailure,
onCancel = {
@ -162,12 +164,17 @@ internal class LegacyScanProcessor @Inject constructor(
}
private suspend inline fun onScanFailure(
analyticsSource: AnalyticsParam.ScreensSources,
error: TangemError,
crossinline onFailure: suspend (TangemError) -> Unit,
crossinline onCancel: () -> Unit,
) {
if (error is TangemSdkError.CardVerificationFailed) {
analyticsEventHandler.send(event = OnboardingAnalyticsEvent.Onboarding.OfflineAttestationFailed)
analyticsEventHandler.send(
event = OnboardingAnalyticsEvent.Onboarding.OfflineAttestationFailed(
analyticsSource,
),
)
val resource = error.localizedDescriptionRes()
val resId = resource.resId ?: R.string.common_unknown_error

View file

@ -66,7 +66,10 @@ internal class CardSettingsViewModel @Inject constructor(
)
private fun scanCard() = viewModelScope.launch {
scanCardProcessor.scan(allowsRequestAccessCodeFromRepository = true)
scanCardProcessor.scan(
analyticsSource = com.tangem.core.analytics.models.AnalyticsParam.ScreensSources.Settings,
allowsRequestAccessCodeFromRepository = true,
)
.doOnSuccess { scanResponse ->
val scannedUserWalletId = UserWalletIdBuilder.scanResponse(scanResponse).build()
if (userWalletId == scannedUserWalletId || scannedUserWalletId == null) {

View file

@ -8,7 +8,7 @@ import com.tangem.tap.features.intentHandler.IntentHandler
internal class OnPushClickedIntentHandler(val analyticsEventHandler: AnalyticsEventHandler) : IntentHandler {
override fun handleIntent(intent: Intent?, isFromForeground: Boolean): Boolean {
val fromPush = intent?.extras?.getBoolean(IS_OPENED_FROM_PUSH) ?: false
val fromPush = intent?.extras?.containsKey(OPENED_FROM_GCM_PUSH) ?: false
return if (fromPush) {
analyticsEventHandler.send(Push.PushNotificationOpened)
@ -19,6 +19,6 @@ internal class OnPushClickedIntentHandler(val analyticsEventHandler: AnalyticsEv
}
companion object {
const val IS_OPENED_FROM_PUSH = "IS_OPENED_FROM_PUSH"
const val OPENED_FROM_GCM_PUSH = "google.sent_time" // every bundle from FCM contains this key
}
}

View file

@ -99,7 +99,7 @@ object OnboardingHelper {
}
}
fun saveWallet(
suspend fun saveWallet(
alreadyCreatedWallet: UserWallet?,
scanResponse: ScanResponse,
accessCode: String? = null,
@ -107,46 +107,42 @@ object OnboardingHelper {
hasBackupError: Boolean = false,
) {
Analytics.setContext(scanResponse)
scope.launch {
val settingsRepository = store.inject(DaggerGraphState::settingsRepository)
when {
// When should save user wallets, then save card without navigate to save wallet screen
store.inject(DaggerGraphState::walletsRepository).shouldSaveUserWalletsSync() -> {
store.dispatchWithMain(
SaveWalletAction.ProvideBackupInfo(
scanResponse = scanResponse,
accessCode = accessCode,
backupCardsIds = backupCardsIds?.toSet(),
),
)
val settingsRepository = store.inject(DaggerGraphState::settingsRepository)
when {
// When should save user wallets, then save card without navigate to save wallet screen
store.inject(DaggerGraphState::walletsRepository).shouldSaveUserWalletsSync() -> {
store.dispatchWithMain(
SaveWalletAction.ProvideBackupInfo(
scanResponse = scanResponse,
accessCode = accessCode,
backupCardsIds = backupCardsIds?.toSet(),
),
)
store.dispatchWithMain(
SaveWalletAction.SaveWalletAfterBackup(
hasBackupError = hasBackupError,
shouldNavigateToWallet = false,
),
)
}
// When should not save user wallets but device has biometry and save wallet screen has not been shown,
// then open save wallet screen
tangemSdkManager.checkCanUseBiometry() && settingsRepository.shouldShowSaveUserWalletScreen() -> {
proceedWithScanResponse(scanResponse, backupCardsIds, hasBackupError, alreadyCreatedWallet)
delay(timeMillis = 1_200)
store.dispatchOnMain(
SaveWalletAction.ProvideBackupInfo(
scanResponse = scanResponse,
accessCode = accessCode,
backupCardsIds = backupCardsIds?.toSet(),
),
)
}
// If device has no biometry and save wallet screen has been shown, then go through old scenario
else -> {
proceedWithScanResponse(scanResponse, backupCardsIds, hasBackupError, alreadyCreatedWallet)
}
store.dispatchWithMain(
SaveWalletAction.SaveWalletAfterBackup(
hasBackupError = hasBackupError,
shouldNavigateToWallet = false,
),
)
}
// When should not save user wallets but device has biometry and save wallet screen has not been shown,
// then open save wallet screen
tangemSdkManager.checkCanUseBiometry() && settingsRepository.shouldShowSaveUserWalletScreen() -> {
proceedWithScanResponse(scanResponse, backupCardsIds, hasBackupError, alreadyCreatedWallet)
delay(timeMillis = 1_200)
store.dispatchWithMain(
SaveWalletAction.ProvideBackupInfo(
scanResponse = scanResponse,
accessCode = accessCode,
backupCardsIds = backupCardsIds?.toSet(),
),
)
}
// If device has no biometry and save wallet screen has been shown, then go through old scenario
else -> proceedWithScanResponse(scanResponse, backupCardsIds, hasBackupError, alreadyCreatedWallet)
}
}

View file

@ -7,6 +7,7 @@ import com.tangem.common.extensions.guard
import com.tangem.common.routing.AppRoute
import com.tangem.common.routing.utils.popTo
import com.tangem.core.analytics.Analytics
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.core.analytics.models.event.OnboardingAnalyticsEvent
import com.tangem.core.ui.R
import com.tangem.core.ui.extensions.resourceReference
@ -356,7 +357,9 @@ private fun handle(action: Action, dispatch: DispatchFunction) {
private fun showCardVerificationFailedDialog(error: TangemError) {
if (error is TangemSdkError.CardVerificationFailed) {
Analytics.send(event = OnboardingAnalyticsEvent.Onboarding.OfflineAttestationFailed)
Analytics.send(
event = OnboardingAnalyticsEvent.Onboarding.OfflineAttestationFailed(AnalyticsParam.ScreensSources.Backup),
)
val resource = error.localizedDescriptionRes()
val resId = resource.resId ?: R.string.common_unknown_error

View file

@ -4,7 +4,6 @@ import android.net.Uri
import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.tangem.common.CompletionResult
import com.tangem.common.card.Card
import com.tangem.common.core.TangemError
import com.tangem.common.core.TangemSdkError
import com.tangem.common.extensions.ifNotNull
import com.tangem.common.extensions.toHexString
@ -12,6 +11,7 @@ import com.tangem.common.routing.AppRoute
import com.tangem.common.routing.AppRouter
import com.tangem.common.services.Result
import com.tangem.core.analytics.Analytics
import com.tangem.core.analytics.models.AnalyticsParam.ScreensSources
import com.tangem.core.analytics.models.event.OnboardingAnalyticsEvent
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.toWrappedList
@ -43,7 +43,6 @@ import com.tangem.tap.common.extensions.*
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.common.redux.global.GlobalAction
import com.tangem.tap.features.demo.DemoHelper
import com.tangem.tap.features.home.redux.HomeAction
import com.tangem.tap.features.onboarding.OnboardingDialog
import com.tangem.tap.features.onboarding.OnboardingHelper
import com.tangem.tap.proxy.redux.DaggerGraphState
@ -52,7 +51,6 @@ import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.rekotlin.Action
import org.rekotlin.Middleware
import timber.log.Timber
object OnboardingWalletMiddleware {
val handler = onboardingWalletMiddleware
@ -203,7 +201,7 @@ private fun handleWalletAction(action: Action) {
}
}
private fun handleFinishBackup(scanResponse: ScanResponse, userWallet: UserWallet? = null) {
private suspend fun handleFinishBackup(scanResponse: ScanResponse, userWallet: UserWallet? = null) {
val backupState = store.state.onboardingWalletState.backupState
val updatedScanResponse = updateScanResponseAfterBackup(scanResponse, backupState)
@ -234,31 +232,14 @@ private fun navigateToWalletScreen() {
}
}
private suspend fun readCard(onSuccess: suspend (ScanResponse) -> Unit, onFailure: (TangemError) -> Unit) {
private suspend fun readCard(): CompletionResult<ScanResponse> {
val shouldSaveAccessCodes = store.inject(DaggerGraphState::settingsRepository).shouldSaveAccessCodes()
store.inject(DaggerGraphState::cardSdkConfigRepository).setAccessCodeRequestPolicy(
isBiometricsRequestPolicy = shouldSaveAccessCodes,
)
store.inject(DaggerGraphState::scanCardProcessor).scan(
analyticsSource = com.tangem.core.analytics.models.AnalyticsParam.ScreensSources.Intro,
onProgressStateChange = { showProgress ->
if (showProgress) {
store.dispatch(HomeAction.ScanInProgress(scanInProgress = true))
} else {
delay(HIDE_PROGRESS_DELAY)
store.dispatch(HomeAction.ScanInProgress(scanInProgress = false))
}
},
onFailure = {
Timber.e(it, "Unable to scan card")
delay(HIDE_PROGRESS_DELAY)
store.dispatch(HomeAction.ScanInProgress(scanInProgress = false))
onFailure(it)
},
onSuccess = onSuccess,
)
return store.inject(DaggerGraphState::scanCardProcessor).scan(analyticsSource = ScreensSources.Intro)
}
private suspend fun loadArtworkForCard(cardId: String, cardPublicKey: ByteArray, defaultArtwork: Uri?): Uri {
@ -476,7 +457,11 @@ private fun handleBackupAction(appState: () -> AppState?, action: BackupAction)
when (val error = result.error) {
is TangemSdkError.CardVerificationFailed -> {
Analytics.send(event = OnboardingAnalyticsEvent.Onboarding.OfflineAttestationFailed)
Analytics.send(
event = OnboardingAnalyticsEvent.Onboarding.OfflineAttestationFailed(
ScreensSources.Backup,
),
)
val resource = error.localizedDescriptionRes()
val resId = resource.resId ?: com.tangem.core.ui.R.string.common_unknown_error
@ -656,23 +641,22 @@ private fun handleBackupAction(appState: () -> AppState?, action: BackupAction)
Analytics.send(Onboarding.Finished())
scope.launch {
store.state.globalState.onboardingState.onboardingManager?.finishActivation(
cardIds = gatherCardIds(backupState, card),
)
}
if (scanResponse == null) {
scope.launch {
readCard(
onSuccess = { newScanResponse ->
handleFinishBackup(newScanResponse)
},
onFailure = {
store.dispatchNavigationAction(AppRouter::pop)
},
launch {
store.state.globalState.onboardingState.onboardingManager?.finishActivation(
cardIds = gatherCardIds(backupState, card),
)
}
} else {
handleFinishBackup(scanResponse)
with(scanResponse) {
if (this == null) {
when (val result = readCard()) {
is CompletionResult.Success -> handleFinishBackup(result.data)
is CompletionResult.Failure -> store.dispatchNavigationAction(AppRouter::pop)
}
} else {
handleFinishBackup(scanResponse = this)
}
}
}
}
is BackupAction.FinishBackup -> {
@ -688,40 +672,39 @@ private fun handleBackupAction(appState: () -> AppState?, action: BackupAction)
scanResponse = requireNotNull(value = scanResponse, lazyMessage = { "ScanResponse is null" }),
backupState = backupState,
)
val userWalletsListManager = store.inject(DaggerGraphState::generalUserWalletsListManager)
when (backupState.startedSource) {
BackupStartedSource.Onboarding -> saveWallet(
userWalletsListManager = userWalletsListManager,
userWallet = userWallet,
scanResponse = scanResponse,
backupState = backupState,
)
BackupStartedSource.CreateBackup -> updateWallet(
userWalletsListManager = userWalletsListManager,
userWallet = userWallet,
backupState = backupState,
)
}
} else {
delay(HIDE_PROGRESS_DELAY)
readCard(
onSuccess = { newScanResponse ->
scanResponse = newScanResponse
userWallet = createUserWallet(newScanResponse, backupState)
},
onFailure = {
when (val result = readCard()) {
is CompletionResult.Failure -> {
store.dispatchNavigationAction(AppRouter::pop)
},
return@launch
}
is CompletionResult.Success -> {
scanResponse = result.data
userWallet = createUserWallet(scanResponse = result.data, backupState = backupState)
}
}
}
val userWalletsListManager = store.inject(DaggerGraphState::generalUserWalletsListManager)
when (backupState.startedSource) {
BackupStartedSource.Onboarding -> saveWallet(
userWalletsListManager = userWalletsListManager,
userWallet = userWallet,
scanResponse = scanResponse,
backupState = backupState,
)
BackupStartedSource.CreateBackup -> updateWallet(
userWalletsListManager = userWalletsListManager,
userWallet = userWallet,
backupState = backupState,
)
}
scope.launch {
userWallet?.let {
if (it.scanResponse.cardTypesResolver.isWallet2() && it.isImported) {
store.inject(DaggerGraphState::walletsRepository).markWallet2WasCreated(it.walletId)
}
if (userWallet.scanResponse.cardTypesResolver.isWallet2() && userWallet.isImported) {
store.inject(DaggerGraphState::walletsRepository).markWallet2WasCreated(userWallet.walletId)
}
}
@ -736,7 +719,7 @@ private fun handleBackupAction(appState: () -> AppState?, action: BackupAction)
// All cardIds may already be activated if the backup was skipped before.
if (notActivatedCardIds.isEmpty()) {
delay(1000)
store.dispatchWithMain(BackupAction.BackupFinished(userWallet?.walletId))
store.dispatchWithMain(BackupAction.BackupFinished(userWallet.walletId))
return@launch
}
@ -744,8 +727,7 @@ private fun handleBackupAction(appState: () -> AppState?, action: BackupAction)
store.state.globalState.onboardingState.onboardingManager?.finishActivation(notActivatedCardIds)
handleFinishBackup(requireNotNull(scanResponse), userWallet)
delay(1000)
store.dispatchWithMain(BackupAction.BackupFinished(userWalletId = userWallet?.walletId))
store.dispatchWithMain(BackupAction.BackupFinished(userWalletId = userWallet.walletId))
}
}

View file

@ -48,7 +48,7 @@ internal class CryptoCurrenciesMocks(private val scanResponse: ScanResponse) {
val network = Network(
id = Network.ID(blockchain.id),
backendId = blockchain.toNetworkId(),
name = blockchain.getNetworkName(),
name = blockchain.fullName,
isTestnet = blockchain.isTestnet(),
derivationPath = getNetworkDerivationPath(
blockchain,
@ -76,7 +76,7 @@ internal class CryptoCurrenciesMocks(private val scanResponse: ScanResponse) {
network = Network(
id = Network.ID(value = blockchain.id),
backendId = "NEVER-MIND",
name = blockchain.getNetworkName(),
name = blockchain.fullName,
currencySymbol = "NEVER-MIND",
derivationPath = Network.DerivationPath.Custom(
value = derivationBlockchain.derivationPath(

View file

@ -0,0 +1,50 @@
FROM ubuntu:24.04
ENV DEBIAN_FRONTEND=noninteractive
ENV ANDROID_HOME=/opt/android-sdk
ENV BUNDLE_PATH=vendor/bundle
ENV PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$ANDROID_HOME/build-tools/34.0.0:$BUNDLE_PATH/bin
ENV LC_ALL=en_US.UTF-8
ENV LANG=en_US.UTF-8
RUN apt-get update && apt-get install -y \
openjdk-17-jdk \
wget \
unzip \
curl \
git \
ruby \
ruby-dev \
build-essential \
&& apt-get clean
RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg && \
chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg && \
echo "deb [signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" > /etc/apt/sources.list.d/github-cli.list && \
apt-get update && apt-get install -y gh && \
apt-get clean
RUN mkdir -p $ANDROID_HOME/cmdline-tools/latest && \
wget https://dl.google.com/android/repository/commandlinetools-linux-9477386_latest.zip -O /tmp/cmdline-tools.zip && \
unzip /tmp/cmdline-tools.zip -d $ANDROID_HOME/cmdline-tools/latest && \
mv $ANDROID_HOME/cmdline-tools/latest/cmdline-tools/* $ANDROID_HOME/cmdline-tools/latest/ && \
rm -rf $ANDROID_HOME/cmdline-tools/latest/cmdline-tools && \
rm -f /tmp/cmdline-tools.zip && \
yes | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --licenses && \
$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager "platform-tools" "platforms;android-31" "platforms;android-34" "build-tools;34.0.0"
RUN wget https://github.com/lzhiyong/android-sdk-tools/releases/download/34.0.3/android-sdk-tools-static-aarch64.zip -O /tmp/android-sdk-tools-static-aarch64.zip && \
unzip /tmp/android-sdk-tools-static-aarch64.zip -d /tmp/android-sdk-tools-static-arm && \
cp -r /tmp/android-sdk-tools-static-arm/build-tools/* $ANDROID_HOME/build-tools/34.0.0/ && \
rm -rf /tmp/android-sdk-tools-static-arm /tmp/android-sdk-tools-static-aarch64.zip
RUN gem install bundler:2.5.23
RUN gem install fastlane -v 2.211.0 -N -V
RUN gem install fastlane-plugin-firebase_app_distribution -v 0.9.1 -N -V
COPY ../Gemfile Gemfile.lock ./
RUN bundle install --jobs=4 --retry=3 --verbose
RUN bundle exec fastlane -v
CMD ["bash"]

View file

@ -0,0 +1,19 @@
FROM ubuntu:24.04
RUN apt-get update && apt-get install -y \
curl \
git \
&& apt-get clean
RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg && \
chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg && \
echo "deb [signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" > /etc/apt/sources.list.d/github-cli.list && \
apt-get update && apt-get install -y gh && \
apt-get clean
RUN curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | bash && \
apt-get install -y git-lfs && \
git lfs install && \
apt-get clean
CMD ["bash"]

View file

@ -0,0 +1,49 @@
#!/bin/bash
set -eo pipefail
# Input args
if [ -z "$1" ]; then
echo "Error: No base branch argument provided or empty string given."
echo "Usage: $0 <base-branch>"
exit 1
fi
base_branch=$1
# Initialize variables to store the latest release branch and merge base
latest_branch=""
latest_merge_base=""
# Source refs to find branches from
local_refs="refs/heads/releases/*" # For debug and development
remote_refs=$(git for-each-ref --sort=-committerdate --format="%(refname:short)" refs/remotes/origin/ | grep -E "origin/[a-zA-Z0-9._-]+_pre_release$")
# Iterate over all remote release branches sorted by commit date (most recent first)
for branch in $remote_refs; do
# Find the common ancestor (merge base) between the base branch and the current branch
merge_base=$(git merge-base "$base_branch" "$branch")
echo "Merge base for branches '$branch' and '$base_branch' is '$merge_base'"
# Update the latest branch and merge base if the current merge base is a descendant of the latest merge base
if [ -z "$latest_merge_base" ] || git merge-base --is-ancestor "$latest_merge_base" "$merge_base"; then
latest_branch="$branch"
latest_merge_base="$merge_base"
fi
done
echo "Latest branch: $latest_branch"
echo "Latest merge base: $latest_merge_base"
# Output validation
if [ -z "$latest_branch" ]; then
echo "Error: Can't find the latest 'pre_release' branch for the base branch '$base_branch'"
exit 2
fi
# Stripping 'origin/' prefix if needed
latest_branch="${latest_branch#origin/}"
echo "$latest_branch" > "find-latest-pre-release-branch.output"
echo "Latest 'pre_release' branch created from '$base_branch' or its ancestor: '$latest_branch'"

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -79,6 +79,8 @@ sealed class AnalyticsParam {
data object Buy : ScreensSources("Buy")
data object Swap : ScreensSources("Swap")
data object Sell : ScreensSources("Sell")
data object Backup : ScreensSources("Backup")
data object Onboarding : ScreensSources("Onboarding")
}
sealed class TxSentFrom(val value: String) {

View file

@ -1,6 +1,7 @@
package com.tangem.core.analytics.models.event
import com.tangem.core.analytics.models.AnalyticsEvent
import com.tangem.core.analytics.models.AnalyticsParam
sealed class OnboardingAnalyticsEvent(
category: String,
@ -11,8 +12,13 @@ sealed class OnboardingAnalyticsEvent(
sealed class Onboarding(
event: String,
params: Map<String, String> = mapOf(),
) : OnboardingAnalyticsEvent(category = "Onboarding", event = event, params = params) {
) : OnboardingAnalyticsEvent(category = "Error", event = event, params = params) {
data object OfflineAttestationFailed : Onboarding(event = "Offline Attestation Failed")
data class OfflineAttestationFailed(
val source: AnalyticsParam.ScreensSources,
) : Onboarding(
event = "Offline Attestation Failed",
params = mapOf(AnalyticsParam.SOURCE to source.value),
)
}
}

View file

@ -87,6 +87,8 @@
<string name="cardano_max_amount_has_token_title">Nicht genug ADA</string>
<string name="common_accept">Akzeptieren</string>
<string name="common_access_denied">Zugang verweigert</string>
<string name="common_add_to_portfolio">Zum Portfolio hinzufügen</string>
<string name="common_add_token">Token hinzufügen</string>
<string name="common_all">Alle</string>
<string name="common_allow">Erlauben</string>
<string name="common_analytics">Analysen</string>
@ -105,7 +107,7 @@
<string name="common_change">Ändern</string>
<string name="common_choose_action">Aktion wählen</string>
<string name="common_claim">Beanspruchen</string>
<string name="common_claim_rewards">Stakingbelohnungen beanstpruchen</string>
<string name="common_claim_rewards">Stakingbelohnungen beanspruchen</string>
<string name="common_close">Schließen</string>
<string name="common_confirm">Bestätigen</string>
<string name="common_continue">Weiter</string>
@ -197,7 +199,7 @@
<string name="common_understand">Ich verstehe</string>
<string name="common_unknown_error">Es ist ein Fehler aufgetreten. Bitte versuche es erneut.</string>
<string name="common_unreachable">Nicht erreichbar</string>
<string name="common_unstake">staking beenden</string>
<string name="common_unstake">Staking beenden</string>
<string name="common_week">woche</string>
<string name="common_with">mit</string>
<string name="common_yes">Ja</string>
@ -312,6 +314,9 @@
<string name="express_status_bought">Gekauft %s</string>
<string name="express_status_buying">Kauf %s</string>
<string name="express_status_buying_active">Kauf %s…</string>
<string name="express_status_hide_button_text">Diese Transaktion ausblenden</string>
<string name="express_status_hide_dialog_text">Sobald dieser Bildschirm ausgeblendet wurde, kann er nicht mehr aufgerufen werden.</string>
<string name="express_status_hide_dialog_title">Bist Du sicher, dass Du die Transaktionsdetails ausblenden willst?</string>
<string name="express_token_list_empty_search">Keine Token gefunden. Bitte versuche eine andere Anfrage</string>
<string name="express_transaction_id">ID: %s</string>
<string name="express_transaction_id_copied">Transaktions-ID kopiert</string>
@ -338,6 +343,8 @@
<string name="give_permission_unlimited">Unbegrenzt</string>
<string name="home_button_order">Karte oder Ring bestellen</string>
<string name="home_button_scan">Karte oder Ring scannen</string>
<string name="hot_crypto_add_token_subtitle">An %s</string>
<string name="hot_crypto_token_network">In %s</string>
<string name="information_generated_with_ai">Diese Informationen wurden mithilfe von KI generiert.\nTippe hier, wenn Du Fehler finden.</string>
<string name="initial_message_change_access_code_body">Um den Zugangscode zu ändern, halte die Karte oder Ring wie oben gezeigt an das Gerät und entferne sie erst am Ende des Vorgangs.</string>
<string name="initial_message_change_passcode_body">Um den Passcode zu ändern, halte die Karte oder Ring wie oben gezeigt an das Gerät und entferne sie erst am Ende des Vorgangs.</string>
@ -654,7 +661,7 @@
<string name="reset_card_with_backup_to_factory_message">Durch das Zurücksetzen auf Werkseinstellungen wird die Wallet vollständig von der ausgewählten Karte oder Ring gelöscht. Du kannst die aktuelle Wallet nicht wiederherstellen oder die Karte oder Ring verwenden, um den Zugangscode wiederherzustellen.</string>
<string name="reset_card_without_backup_to_factory_message">Beim Zurücksetzen auf die Werkseinstellungen wird die Wallet der ausgewählten Karte oder Ring vollständig gelöscht und aus der App entfernt. Es ist nicht möglich, die aktuelle Wallet wiederherzustellen.</string>
<string name="ring_promo_text">Ringbesitzer erhalten bis zum 15.11. 3 provisionsfreie Swaps auf Changelly!</string>
<string name="ring_promo_title">Jetzt mit 0 %% Gebühren tauschen!</string>
<string name="ring_promo_title">Jetzt mit 0 % Gebühren tauschen!</string>
<string name="save_user_wallet_agreement_access_description">Melde dich bei der App an und überprüfe dein Guthaben, ohne die Karte oder Ring zu scannen</string>
<string name="save_user_wallet_agreement_access_title">Zugriff auf die App</string>
<string name="save_user_wallet_agreement_allow_biometrics">Nutzung biometrischer Daten zulassen</string>
@ -786,6 +793,8 @@
<string name="staking_migrate">Migrieren</string>
<string name="staking_native">Natives Staking</string>
<string name="staking_no_validators_error_message">Derzeit sind keine aktiven Validatoren für das Staking verfügbar. Bitte versuchen Sie es später erneut.</string>
<string name="staking_notification_additional_ada_deposit_text">Beim Staking im Cardano Netzwerk wird das gesamte Guthaben genutzt. Zusätzlich werden 2 ADA reserviert und nach dem Unstaking zurückgegeben. Deine ADA sind während des Stakings nicht gesperrt.</string>
<string name="staking_notification_additional_ada_deposit_title">Einzelheiten zum ADA-Staking</string>
<string name="staking_notification_claim_rewards_text">Verdiente Belohnungen werden an Deine Wallet gesendet und stehen Dir sofort zur Verfügung</string>
<string name="staking_notification_earn_rewards_text">Stake sicher und verdienen Belohnungen</string>
<string name="staking_notification_earn_rewards_text_daily">Sicher staken und tägliche Belohnungen verdienen.</string>
@ -799,6 +808,8 @@
<string name="staking_notification_earn_rewards_title">Verdiene Staking-Belohnungen</string>
<string name="staking_notification_low_staked_balance_text">Dein verbleibender Stakingbetrag ist zu niedrig, um den Einsatz aufzuheben. Du musst mehr Staken, um den Mindestbetrag zum Aufheben des Einsatzes zu erreichen.</string>
<string name="staking_notification_low_staked_balance_title">Niedriges Stakingguthaben</string>
<string name="staking_notification_minimum_balance_error_text">Für erneutes Staking sind mindestens %1$s %2$s erforderlich. Bitte lade Dein Guthaben auf.</string>
<string name="staking_notification_minimum_balance_error_title">Nicht genug %s</string>
<string name="staking_notification_network_error_text">Aufgrund von Netzwerkproblemen ist Staking derzeit nicht verfügbar. Bitte versuche es später erneut.</string>
<string name="staking_notification_new_validator_funds_transfer">Beim Staking im %1$s -Netzwerk mit einem neuen Validator werden alle zuvor eingesetzten Kryptos automatisch an diesen Validator übertragen</string>
<string name="staking_notification_restake_rewards_text">Reinvestiert Deine verdienten Prämien in Deinen Einsatzbetrag und erhöht so den potenziellen Gewinn.</string>
@ -806,7 +817,7 @@
<string name="staking_notification_stake_entire_balance_text">Du bist dabei, Dein gesamtes Guthaben zu staken. Wir empfehlen, einen kleinen Betrag übrig zu lassen, um die Netzwerkgebühren für die Aufhebung des Stakes oder das Einfordern von Prämien abzudecken.</string>
<string name="staking_notification_unlock_text">Entsperre dein Geld, um es aus dem Staking-Prozess abzuheben. Das Freischalten nimmt %s.</string>
<string name="staking_notification_unstake_cosmos_text">Nach Ablauf der 21-tägigen Bindungsfrist kannst Du über Dein Guthaben verfügen. Die Prämie wird zusammen mit dem ungestaketen Guthaben abgehoben.</string>
<string name="staking_notification_unstake_text">Deine Assets steht Dir nach Ablauf der Frist für die Aufhebung der Bindung %s zur Verfügung.</string>
<string name="staking_notification_unstake_text">Deine Assets stehen Dir nach Ablauf der Frist für die Aufhebung der Bindung %s zur Verfügung.</string>
<string name="staking_notification_withdraw_text">Du kannst Dein Guthaben jetzt abheben. Es steht Dir sofort zur Verfügung.</string>
<string name="staking_notifications_revote_tron_text">Wenn du im Tron-Netzwerk mit einem neuen Validator stakest, werden alle zuvor eingesetzten Assets automatisch an diesen Validator übertragen.</string>
<string name="staking_preparing">Vorbereitung</string>
@ -838,7 +849,7 @@
<string name="staking_tap_to_unlock_or_vote">Tippe zum Entsperren oder Abstimmen</string>
<string name="staking_tap_to_withdraw">Zum abheben antippen</string>
<string name="staking_title_stake">Stake %s</string>
<string name="staking_title_unstake">Staking beenden%s</string>
<string name="staking_title_unstake">Staking beenden %s</string>
<string name="staking_transaction_in_progress_text">Die Transaktion wird bearbeitet! Derzeit findet eine Validierung in der Blockchain statt. Dies kann einige Minuten dauern.</string>
<string name="staking_unbonding">Lösen der Bindungen</string>
<string name="staking_unlocked_locked">Gelocktes unlocken</string>
@ -912,6 +923,7 @@
<string name="token_swap_changelly_promotion_message">Tausche diesen Token gegen einen anderen zu %1$s Servicegebühren von Februar %2$s-%3$s.</string>
<string name="token_swap_changelly_promotion_title">Tausche mit Changelly, %s Gebühren</string>
<string name="token_swap_promotion_button">Jetzt tauschen</string>
<string name="tokens_list_hot_crypto_header">Hot Krypto 🔥</string>
<string name="tokens_list_unavailable_to_purchase_header">Nicht verfügbar zum Kauf</string>
<string name="tokens_list_unavailable_to_sell_header">Nicht zum Verkauf verfügbar</string>
<string name="tokens_list_unavailable_to_swap_header">Nicht verfügbar für Tausch von %s</string>
@ -945,7 +957,7 @@
<string name="user_push_notification_agreement_argument_two">Sei der Erste, der von neuen Aktionen erfährt</string>
<string name="user_push_notification_agreement_header">Möchtest du Push-Benachrichtigungen verwenden?</string>
<string name="user_wallet_list_add_button">Neues Wallet hinzufügen</string>
<string name="user_wallet_list_delete_prompt">Möchtest du diese Wallet wirklich löschen?</string>
<string name="user_wallet_list_delete_prompt">Möchtest Du diese Wallet wirklich entfernen?</string>
<string name="user_wallet_list_error_unable_to_unlock">Es ist ein Fehler aufgetreten, bitte scanne deine Karte oder Ring, um sich anzumelden</string>
<string name="user_wallet_list_error_wallet_already_saved">Dieses Wallet wurde bereits gespeichert, du kannst ein weiteres hinzufügen</string>
<string name="user_wallet_list_rename_popup_error_already_exists">Die Wallet mit dem Namen %s existiert bereits</string>
@ -955,7 +967,7 @@
<string name="user_wallet_list_unlock_all_with">Alle mit %s freischalten</string>
<string name="wallet_balance_blockchain_unreachable_try_later">Blockchain ist nicht erreichbar. Versuche es später nochmal</string>
<string name="wallet_balance_missing_derivation">Karte oder Ring scannen</string>
<string name="wallet_been_activated_message">Diese Wallet wurde bereits früher aktiviert.\nWenn es nicht von Dir durchgeführt wurde, wende Dich bitte an den Support.\nTangem verkauft niemals Wallets zusammen mit dem vorgenerierten Zugangscode.</string>
<string name="wallet_been_activated_message">Dieses Wallet wurde bereits früher aktiviert. \n Wenn dies nicht von Dir durchgeführt wurde, wende Dich bitte an den Support. \n Tangem verkauft niemals Wallets zusammen mit vorgenerierten Zugangscodes.</string>
<string name="wallet_connect_alert_sign_message">Aufforderung zum Signieren einer Nachricht. \n\n %s</string>
<string name="wallet_connect_bnb_sign_message">Dapp %1$s, mit der Bitte um\nBNB-Transaktion zu unterzeichnen.\n\n%2$s</string>
<string name="wallet_connect_bnb_trade_order_message">Handelsauftrag für %1$s\n Preis: %2$s\n Zu erhaltender Betrag: %3$s\n Zu zahlender Betrag: %4$s</string>
@ -993,7 +1005,7 @@
<string name="wallet_network_group_title">%s Netzwerk</string>
<string name="wallet_notification_address_copied">Die Adresse wurde erfolgreich kopiert</string>
<string name="wallet_notification_no_internet">Keine Internetverbindung</string>
<string name="wallet_promo_banner_button_title">Jetzt mit 10 %% Rabatt kaufen</string>
<string name="wallet_promo_banner_button_title">Jetzt mit 10 % Rabatt kaufen</string>
<string name="wallet_promo_banner_description">Greife auf 13.000+ Kryptowährungen zu. Kaufe, verkaufe, tausche und stake Sie mit einem einzigen Fingertipp.\nVerbinde bis zu drei Karten für ein Backup.</string>
<string name="wallet_promo_banner_title">Entdecke die Tangem Wallet</string>
<string name="wallet_settings_title">Wallet-Einstellungen</string>
@ -1044,6 +1056,7 @@
<string name="warning_kaspa_unfinished_token_transaction_discard_message">Bist Du sicher, dass Du die Transaktion stornieren willst? Du kannst die Transaktion nicht erneut starten.</string>
<string name="warning_kaspa_unfinished_token_transaction_message">Deine Transaktion mit einem Betrag von %1$s %2$s wurde nicht abgeschlossen. Du kannst versuchen, diese erneut abzuschließen.</string>
<string name="warning_kaspa_unfinished_token_transaction_title">Du hast eine nicht abgeschlossene Transaktion</string>
<string name="warning_last_balance_updated_time">Letzte Aktualisierung war %s</string>
<string name="warning_low_signatures_message">Auf dieser Karte oder Ring sind nur noch %s Unterschriften übrig. Du musst dein gesamtes Guthaben abheben.</string>
<string name="warning_low_signatures_title">Geringe Anzahl von Unterschriften</string>
<string name="warning_manage_tokens_legacy_derivation_message">Token in verschiedenen Netzwerken können unterschiedliche Adressen haben. Überprüfe bei der Überweisung noch einmal, ob deine Adresse mit der des Netzwerks übereinstimmt.</string>
@ -1067,7 +1080,7 @@
<string name="warning_rent_fee_title">Netzmietgebühr erforderlich</string>
<string name="warning_seedphrase_issue_answer_no">Vielen Dank! Alles erledigt! Keine weiteren Maßnahmen erforderlich.</string>
<string name="warning_seedphrase_issue_answer_yes">Sie werden jetzt auf die offizielle Tangem-Website weitergeleitet. Bitte lesen und befolgen Sie dort die Anweisungen.</string>
<string name="warning_seedphrase_issue_message">Haben Sie jemals das Support-Team von Tangem direkt über diese Anwendung kontaktiert?</string>
<string name="warning_seedphrase_issue_message">Hast Du das Tangem-Supportteam schon einmal direkt über diese Anwendung kontaktiert?</string>
<string name="warning_seedphrase_issue_title">Verpflichtendes Sicherheitsupdate</string>
<string name="warning_send_blocked_funds_for_fee_message">%1$s ist ein Vermögenswert im %2$s Netzwerk. Um eine %3$s Transaktion durchzuführen, musst du etwas %4$s (%5$s) einzahlen, um die Netzwerkgebühr zu decken.</string>
<string name="warning_send_blocked_funds_for_fee_title">Unzureichende %1$s zur Deckung der Netzgebühr</string>
@ -1076,6 +1089,7 @@
<string name="warning_solana_rent_fee_message">Das Solana-Netzwerk erhebt alle 2 Tage eine Miete von %1$s. Konten, die sich die Miete nicht leisten können, werden aus dem Netzwerk gelöscht. Hinterlege deinem Konto mit mehr als %2$s, um es kostenlos zu nutzen.</string>
<string name="warning_some_networks_unreachable_message">Wischen Sie nach unten, um zu aktualisieren, oder versuchen Sie es später erneut.</string>
<string name="warning_some_networks_unreachable_title">Einige Netzwerke sind nicht erreichbar</string>
<string name="warning_some_token_balances_not_updated">Einige Token-Guthaben konnten nicht aktualisiert werden</string>
<string name="warning_testnet_card_message">Dies ist eine Testnet-Karte. Sie kann keine Transaktionen verarbeiten und sollte nur zu Test- und Entwicklungszwecken verwendet werden.</string>
<string name="warning_testnet_card_title">Nur für Testzwecke</string>
<string name="welcome_interrupted_backup_alert_discard">Verwerfen</string>

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<string name="action_buttons_buy_empty_search_message">¿No encuentra el token en su billetera? Consulte los mercados para encontrarlo y añadirlo a la compra</string>
<string name="action_buttons_buy_empty_search_message">¿No encuentra el token en su billetera? Consulte la sección de Mercados para encontrarlo y añadirlo a la compra</string>
<string name="action_buttons_sell_empty_search_message">¿No encuentra el token en su billetera? Consulte los mercados para encontrarlo y añadirlo a la venta</string>
<string name="action_buttons_sell_navigation_bar_title">Vender</string>
<string name="action_buttons_service_loading_alert_message">Esto puede tardar unos segundos. Inténtelo de nuevo más tarde.</string>
@ -28,8 +28,8 @@
<string name="alert_failed_to_send_transaction_message">Razón: %s</string>
<string name="alert_failed_to_send_transaction_title">No se puede completar una transacción</string>
<string name="alert_manage_tokens_unsupported_blockchain_by_card_message">El seleccionado no admite la red %1$s</string>
<string name="alert_manage_tokens_unsupported_curve_message">Para activar el %1$s cifrado criptográfico de la blockchain, necesitarás reiniciar la billetera a los ajustes de fábrica. Por favor, retire sus fondos antes de hacerlo para asegurarte de no perderlos, y luego complete el proceso de reinicio. El acceso a la billetera actual no será posible después del reinicio.</string>
<string name="alert_manage_tokens_unsupported_message">Esta tarjeta no admite %1$s tokens de red debido a una limitación del firmware.</string>
<string name="alert_manage_tokens_unsupported_curve_message">Para activar el %1$s cifrado criptográfico de la blockchain, necesitarás reiniciar la billetera a los ajustes de fábrica. Por favor, retire sus fondos antes de hacerlo para asegurarse no perderlos, y luego complete el proceso de reinicio. El acceso a la billetera actual no será posible después del reinicio.</string>
<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_default_fee">Tarifa por defecto</string>
@ -39,7 +39,7 @@
<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_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 interactuar con su tarjeta.</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>
<string name="app_settings_saved_wallet_footer">Habilite para vincular todos las billeteras a la app Tangem. Se requerirá autenticación biométrica para desbloquear la app. La firma de transacciones requiere tocar su tarjeta Tangem.</string>
<string name="app_settings_theme_mode_dark">Oscuro</string>
@ -51,6 +51,8 @@
<string name="balance_hidden_do_not_show_button">No mostrar de nuevo</string>
<string name="balance_hidden_got_it_button">Entendido</string>
<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_lockout_permanent_warning_description">Por favor, escanee la tarjeta/anillo</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_title">Demasiados intentos</string>
@ -64,17 +66,17 @@
<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>
<string name="card_settings_action_sheet_reset">Reiniciar</string>
<string name="card_settings_action_sheet_reset">Resetear</string>
<string name="card_settings_action_sheet_title">¿Está seguro de que quiere hacer esto?</string>
<string name="card_settings_change_access_code">Cambiar código de acceso</string>
<string name="card_settings_change_access_code_footer">El código de acceso se cambiará solo en esta tarjeta o este anillo</string>
<string name="card_settings_completed_reset_alert_message">Todas las tarjetas de la billetera seleccionada se han restablecido a la configuración de fábrica. Ahora puedes crear una nueva billetera.</string>
<string name="card_settings_completed_reset_alert_message">Todos los dispositivos de la billetera seleccionada se han restablecido a la configuración de fábrica. Ahora puedes crear una nueva billetera.</string>
<string name="card_settings_completed_reset_alert_title">Reinicio completado</string>
<string name="card_settings_continue_reset_alert_message">¿Quiere restablecer el siguiente dispositivo en esta billetera?</string>
<string name="card_settings_continue_reset_alert_title">Reinicio de tarjeta</string>
<string name="card_settings_interrupted_reset_alert_message">Recomendamos completar el proceso de reinicio para todas las tarjetas en esta billetera.</string>
<string name="card_settings_continue_reset_alert_title">Reseteo de billetera</string>
<string name="card_settings_interrupted_reset_alert_message">Recomendamos completar el proceso de reinicio para todos los dispositivos en esta billetera.</string>
<string name="card_settings_interrupted_reset_alert_title">No ha reseteado todas sus dispositivos Tangem</string>
<string name="card_settings_reset_card_to_factory">Restablecer a ajustes de fábrica</string>
<string name="card_settings_reset_card_to_factory">Resetear a configuración de fábrica</string>
<string name="card_settings_security_mode">Modo de seguridad</string>
<string name="card_settings_title">Ajustes del dispositivo</string>
<string name="cardano_coin_will_be_send_with_token_description">Además de la tarifa de red, la red Cardano cobra %1$s ADA al realizar transacciones con el %2$s token</string>
@ -234,7 +236,7 @@
<string name="details_manage_security_access_code">Código de acceso</string>
<string name="details_manage_security_access_code_description">Deberá ingresar la contraseña correcta antes de escanear la tarjeta.</string>
<string name="details_manage_security_long_tap">Sostenga la tarjeta firmemente</string>
<string name="details_manage_security_long_tap_description">Este mecanismo protege contra ataques sin contacto a la tarjeta. Hay un retraso entre la recepción y la ejecución del pedido. Después de la primera transacción firmada, ese teléfono se asociará con la tarjeta y las transacciones se firmarán inmediatamente.</string>
<string name="details_manage_security_long_tap_description">Este mecanismo protege contra los ataques de proximidad a una tarjeta o anillo. Aplicará un retardo entre la recepción y la ejecución de un comando.</string>
<string name="details_manage_security_passcode">Contraseña</string>
<string name="details_manage_security_passcode_description">Antes de ejecutar un comando que cambie el estado de la tarjeta, deberá ingresar una contraseña.</string>
<string name="details_referral_title">Programa de referidos</string>
@ -251,14 +253,14 @@
<string name="details_title">Detalles</string>
<string name="disclaimer_error_loading">Compruebe su conexión a internet o cambia a una red diferente</string>
<string name="disclaimer_title">Condiciones de uso</string>
<string name="error_wrong_wallet_tapped">Ha usado una tarjeta de otro wallet. Toque la tarjeta asociada con esta billetera</string>
<string name="error_wrong_wallet_tapped">Ha usado una tarjeta de otra billetera. Toque la tarjeta asociada con esta billetera</string>
<string name="exchange_tokens_available_tokens_header">Mis tokens</string>
<string name="exchange_tokens_empty_tokens">Aún no ha añadido ningún token. Agregue tokens a través de Market para hacer swap</string>
<string name="exchange_tokens_unavailable_tokens_header">No se puede intercambiar por %s</string>
<string name="express_by_provider">Proporcionado por</string>
<string name="express_cex_status_button_title">Estado</string>
<string name="express_choose_providers_subtitle">Tangem ofrece swaps de tokens a través de proveedores externos según los términos de cada proveedor</string>
<string name="express_choose_providers_title">Elige un proveedor</string>
<string name="express_choose_providers_title">Elija proveedor</string>
<string name="express_error_code">Ha ocurrido un error. Código: %s</string>
<string name="express_error_provider_amount_roundup">Error %1$s. El proveedor seleccionado no puede procesar la transacción especificada. Por favor, redondee el valor a %2$s o cámbielo</string>
<string name="express_error_swap_pair_unavailable">El proveedor seleccionado no está disponible actualmente. Inténtelo de nuevo más tarde. (Código: %s)</string>
@ -334,7 +336,7 @@
<string name="give_permission_swap_subtitle" formatted="false">Para continuar, de autorización a los smart contracts de %1s para usar su %2s</string>
<string name="give_permission_title">Dar autorización</string>
<string name="give_permission_unlimited">Ilimitado</string>
<string name="home_button_order">Ordenar </string>
<string name="home_button_order">Pedir Tangem</string>
<string name="home_button_scan">Escanee</string>
<string name="information_generated_with_ai">Esta información fue generada con IA.\nPulse aquí si encuentra algún error.</string>
<string name="initial_message_change_access_code_body">Para cambiar el código de acceso coloque la tarjeta o el anillo como se muestra arriba y no lo retire hasta el fin de la operación</string>
@ -342,7 +344,7 @@
<string name="initial_message_create_wallet_body">Para crear la billetera, coloque la tarjeta o el anillo como se muestra arriba y no la retire hasta el fin de la operación</string>
<string name="initial_message_create_wallet_body_ring">Para crear la billetera, ponga el anillo como se muestra arriba y manténgala hasta que termine la operación.</string>
<string name="initial_message_reset_backup_card_header">Toque la tarjeta no. %s de la billetera</string>
<string name="initial_message_scan_header">Coloque para escanear</string>
<string name="initial_message_scan_header">Acerque para escanear</string>
<string name="initial_message_sign_header">Toque para firmar</string>
<string name="initial_message_tap_header">Coloque la tarjeta o el anillo</string>
<string name="key_invalidated_warning_description">Ha actualizado la biometría, escanee su tarjeta o anillo para entrar</string>
@ -357,7 +359,7 @@
<string name="main_empty_tokens_list_message">Para comenzar a seguir tus activos crypto y transacciones, agregue tokens</string>
<string name="main_manage_tokens">Gestionar tokens</string>
<string name="main_scan_card_warning_view_subtitle">Para acceder a todas las redes necesita escanear la tarjeta</string>
<string name="main_scan_card_warning_view_title">Escanee su tarjeta</string>
<string name="main_scan_card_warning_view_title">Escanee su tarjeta o anillo</string>
<string name="main_swap_changelly_promotion_message">Benefíciese de %1$s tarifa de servicio en intercambios a través de Changelly del %2$s al %3$s de febrero</string>
<string name="main_swap_changelly_promotion_title">Intercambio con Changelly, %s tarifa</string>
<string name="main_tokens">Tokens</string>
@ -496,7 +498,7 @@
<string name="onboarding_access_code_repeat_code_title">Vuelva a introducir su código de acceso</string>
<string name="onboarding_access_code_too_short">El código de acceso debe tener al menos 4 caracteres</string>
<string name="onboarding_access_codes_doesnt_match">El código de acceso introducido no coincide con el código de acceso inicial</string>
<string name="onboarding_activation_error_message">Por favor repita la operación. La tarjeta se restablecerá a la configuración de fábrica.</string>
<string name="onboarding_activation_error_message">Por favor repita la operación. La tarjeta/anillo se restablecerá a la configuración de fábrica.</string>
<string name="onboarding_activation_error_title">Error de activación</string>
<string name="onboarding_add_tokens">Agregar tokens</string>
<string name="onboarding_alert_message_not_max_backup_cards_added">Ha agregado una tarjeta/anillo de backup. Cuando el proceso de backup finalice, no podrá añadir más dispositivos de backup. Si tiene otra tarjeta o anillo, agréguela al backup. ¿Quiere continuar el proceso de backup?</string>
@ -601,7 +603,7 @@
<string name="onramp_settings_residence_description">Seleccione el país correcto para garantizar opciones de pago y servicios precisos.</string>
<string name="onramp_settings_title">Ajustes</string>
<string name="onramp_statuses_view_footer">Puede comprobar el estado de la transacción desde la página del token.</string>
<string name="onramp_transaction_status_footer_text">Puede comprobar el estado de la transacción desde la página del token</string>
<string name="onramp_transaction_status_footer_text">Puede comprobar el estado de la transacción desde la página detallada del token</string>
<string name="onramp_via">Vía</string>
<string name="organize_tokens_group">Agrupar</string>
<string name="organize_tokens_sort_by_balance">Por saldo</string>
@ -646,14 +648,14 @@
<item quantity="one">%d billetera</item>
<item quantity="other">%d billeteras</item>
</plurals>
<string name="reset_card_to_factory_button_title">Restablecer la tarjeta</string>
<string name="reset_card_to_factory_button_title">Resetear la tarjeta</string>
<string name="reset_card_to_factory_condition_1">Entiendo que después de realizar esta acción, ya no tendré acceso a la billetera actual</string>
<string name="reset_card_to_factory_condition_2">Entiendo que no puedo usar esta tarjeta para recuperar mi código de acceso en las otras tarjetas de la wallet actual</string>
<string name="reset_card_with_backup_to_factory_message">El restablecimiento de fábrica eliminará completamente la billetera de la tarjeta seleccionada. No podrá restaurar la billetera actual ni usar la tarjeta para recuperar el código de acceso.</string>
<string name="reset_card_without_backup_to_factory_message">El restablecimiento de fábrica eliminará completamente la billetera de la tarjeta seleccionada y lo eliminará de la app. No podrá restaurar la billetera actual.</string>
<string name="reset_card_without_backup_to_factory_message">El reseteo a valores de fábrica eliminará completamente la billetera de la tarjeta/anillo seleccionado y lo eliminará de la app. No podrá restaurar la billetera actual.</string>
<string name="ring_promo_text">Si tienes un Anillo Tangem, ¡3 swaps sin comisión en Changelly hasta el 15/11!</string>
<string name="ring_promo_title">¡Intercambia con 0%% de comisión!</string>
<string name="save_user_wallet_agreement_access_description">Inicie sesión en la app y comprueba su saldo sin escanear la tarjeta</string>
<string name="ring_promo_title">¡Intercambia con 0% de comisión!</string>
<string name="save_user_wallet_agreement_access_description">Inicie sesión en la app y comprueba su saldo sin escanear la tarjeta o el anillo</string>
<string name="save_user_wallet_agreement_access_title">Acceder a la app</string>
<string name="save_user_wallet_agreement_allow_biometrics">Permitir el uso de biometría</string>
<string name="save_user_wallet_agreement_code_description_biometrics">Se solicitará la biometría en lugar del código de acceso para interactuar con su billetera</string>
@ -662,9 +664,9 @@
<string name="save_user_wallet_agreement_enroll_biometrics_title">Activar la autorización biométrica</string>
<string name="save_user_wallet_agreement_header_biometrics">¿Le gustaría usar la biometría?</string>
<string name="save_user_wallet_agreement_notice">Tenga en cuenta que realizar una transacción con sus fondos seguirá requiriendo su tarjeta</string>
<string name="scan_card_settings_button">Escanee su tarjeta</string>
<string name="scan_card_settings_message">Escanee la tarjeta para cambiar sus ajustes. Los cambios afectarán solo a la tarjeta que has escaneado y no afectarán a otras tarjetas vinculadas a su billetera.</string>
<string name="scan_card_settings_title">¡Prepare su tarjeta!</string>
<string name="scan_card_settings_button">Escanear tarjeta o anillo</string>
<string name="scan_card_settings_message">Escanee la tarjeta o el anillo para cambiar su configuración. Los cambios afectarán solo a la tarjeta o el anillo que haya escaneado y no afectarán a otros dispositivos vinculados a su billetera.</string>
<string name="scan_card_settings_title">¡Prepare su tarjeta/anillo!</string>
<string name="security_alert_title">Alerta de seguridad</string>
<string name="selling_insufficient_balance_alert_message">No tiene fondos suficientes en su saldo para vender esta criptomoneda. Deposite el activo deseado para continuar.</string>
<string name="selling_insufficient_balance_alert_title">Saldo insuficiente</string>
@ -772,7 +774,7 @@
<string name="staking_details_reward_claiming_info">Método para recibir recompensas por apuesta.\nPuede ser automático, donde la recompensa se acredita en tu dirección, o manual, donde debes retirar la recompensa creando una transacción para recibirla.</string>
<string name="staking_details_reward_schedule">Calendario de recompensas</string>
<string name="staking_details_reward_schedule_info">Este es un cronograma que determina cuándo los participantes reciben sus recompensas. La duración de la distribución de recompensas puede variar ligeramente según el validador y la carga de la red.</string>
<string name="staking_details_rewards_to_claim">Recompensas para reclamar: %s</string>
<string name="staking_details_rewards_to_claim">Recompensas : %s</string>
<string name="staking_details_title">Staking %s</string>
<string name="staking_details_unbonding_period">Periodo de disociación</string>
<string name="staking_details_unbonding_period_info">El período que debes esperar después de solicitar el retiro de fondos del staking antes de que los tokens estén disponibles.</string>
@ -857,7 +859,7 @@
<string name="story_awe_title">Billetera de hardware revolucionaria</string>
<string name="story_backup_description">Hasta 3 tarjetas físicas o anillos por billetera</string>
<string name="story_backup_title">Backup ultra seguro</string>
<string name="story_currencies_description">Una billetera de hardware para su Bitcoin, Ethereum y muchas más monedas simultáneamente todo en una sola tarjeta</string>
<string name="story_currencies_description">Una billetera de hardware para su Bitcoin, Ethereum y muchas más monedas simultáneamente todo en una sola tarjeta o anillo</string>
<string name="story_currencies_title">Miles de monedas</string>
<string name="story_finish_description">Úselo en cualquier lugar, en cualquier momento. Sin cables ni baterías. Solo toque la tarjeta con su teléfono cuando necesites su cripto.</string>
<string name="story_finish_title">La billetera para todos</string>
@ -871,7 +873,7 @@
<string name="swapping_alert_cex_description_with_slippage">El monto incluye:\n• tarifas del proveedor de servicios\n• tarifas de red por enviar %1$s desde el intercambio a la dirección del usuario. \n\nEl slippage del proveedor puede alcanzar el %2$s</string>
<string name="swapping_alert_dex_description">El importe incluye los honorarios del proveedor de servicios.</string>
<string name="swapping_alert_dex_description_with_slippage">El importe incluye las tarifas del proveedor de servicios. \n\nEl slippage del proveedor puede alcanzar el %s</string>
<string name="swapping_alert_title">Tarifa</string>
<string name="swapping_alert_title">Información</string>
<string name="swapping_approve_information_text">Todos los exchanges descentralizados requieren aprobaciones para evitar que los smart contracts accedan a su billetera sin su permiso. Por diseño, los smart contracts no pueden acceder a tus tokens a menos que lo apruebes. Al \"desbloquear\" sus tokens, autoriza al smart contract de 1-inch a gastarlos. Los mineros de la red reciben una tarifa de gas (pagada por voz) para registrar esta acción en la blockchain. Puede intercambiar su token después de dar la aprobación.</string>
<string name="swapping_approve_information_title">Aprobar</string>
<string name="swapping_fee_estimation_error_text">Error en la estimación de la tarifa. Envíe sus comentarios al servicio de asistencia.</string>
@ -910,6 +912,7 @@
<string name="token_swap_changelly_promotion_message">Cambie este token por otro por una tarifa de servicio de %1$s del %2$s al %3$s de febrero.</string>
<string name="token_swap_changelly_promotion_title">Intercambio con Changelly, %s tarifa</string>
<string name="token_swap_promotion_button">Intercambie ahora</string>
<string name="tokens_list_hot_crypto_header">Crypto-monnaies populaire 🔥</string>
<string name="tokens_list_unavailable_to_purchase_header">No disponible para compra</string>
<string name="tokens_list_unavailable_to_sell_header">No disponible para vender</string>
<string name="tokens_list_unavailable_to_swap_header">No disponible para cambio desde %s</string>
@ -953,7 +956,7 @@
<string name="user_wallet_list_unlock_all_with">Desbloquear todo con %s</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 junto con el código de acceso generado previamente.</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 junto con un código de acceso generado previamente.</string>
<string name="wallet_connect_alert_sign_message">Solicitud para firmar un mensaje.\n\n%s</string>
<string name="wallet_connect_bnb_sign_message">Dapp %1$s, solicitando\nfirmar transacción BNB.\n\n%2$s</string>
<string name="wallet_connect_bnb_trade_order_message">Orden de intercambio por %1$s\nPrecio: %2$s\nCantidad a recibir: %3$s\nCantidad a pagar: %4$s</string>
@ -991,15 +994,15 @@
<string name="wallet_network_group_title">%s red</string>
<string name="wallet_notification_address_copied">La dirección se copió correctamente</string>
<string name="wallet_notification_no_internet">Sin conexión a internet</string>
<string name="wallet_promo_banner_button_title">Consíguelo ahora con un 10 %% de descuento</string>
<string name="wallet_promo_banner_button_title">Consíguelo ahora con un 10 % de descuento</string>
<string name="wallet_promo_banner_description">Accede a más de 13 000 criptomonedas. Compra, vende, intercambia y realiza staking con un solo toque.\nVincula hasta tres tarjetas para hacer copias de seguridad.</string>
<string name="wallet_promo_banner_title">Descubre Tangem Wallet</string>
<string name="wallet_settings_title">Ajusta de la wallet</string>
<string name="wallet_settings_title">Ajustes de la wallet</string>
<string name="wallet_title">Tangem</string>
<string name="warning_access_denied_message">Use %s o escanee una tarjeta/anillo para desbloquear el acceso a su billetera</string>
<string name="warning_approval_in_progress_message">El proceso de obtención de permisos está actualmente en marcha y se completará pronto.</string>
<string name="warning_approval_in_progress_title">Aprobación en curso</string>
<string name="warning_backup_errors_message">Parece que la activación de la tarjeta no ha ido correctamente. Esto puede deberse a un problema con el módulo NFC de su dispositivo o a una mala conexión de la tarjeta de su dispositivo. Comuníquese con nuestro equipo de soporte para obtener ayuda.</string>
<string name="warning_backup_errors_message">Parece que la activación de la tarjeta no ha funcionado correctamente. Esto puede deberse a un problema con el módulo NFC de su dispositivo o a una mala conexión de la tarjeta con su dispositivo. Comuníquese con nuestro equipo de soporte para obtener ayuda.</string>
<string name="warning_backup_errors_title">Error de activación</string>
<string name="warning_beacon_chain_retirement_content">El 3 de diciembre de 2024, la red BEP-2 fue desactivada por decisión de los desarrolladores de la red y ya no es compatible</string>
<string name="warning_beacon_chain_retirement_title">BNB Beacon Chain se cerrará</string>
@ -1063,7 +1066,7 @@
<string name="warning_rate_app_title">¿Disfrutando de Tangem?</string>
<string name="warning_receive_blocked_hedera_token_association_required_message">Deba asociar su token antes de recibir tokens</string>
<string name="warning_rent_fee_title">Se requiere tarifa de alquiler de red</string>
<string name="warning_seedphrase_issue_answer_no">¡Gracias! ¡Todo está listo! No se requieren más acciones.</string>
<string name="warning_seedphrase_issue_answer_no">¡Gracias! ¡Todo listo! No se requieren más acciones.</string>
<string name="warning_seedphrase_issue_answer_yes">Ahora será redirigido al sitio web oficial de Tangem. Por favor, lea y siga las instrucciones allí indicadas.</string>
<string name="warning_seedphrase_issue_message">¿Alguna vez contactó al equipo de soporte de Tangem directamente desde esta aplicación?</string>
<string name="warning_seedphrase_issue_title">Actualización de seguridad obligatoria</string>
@ -1072,7 +1075,7 @@
<string name="warning_solana_fee_message">La red Solana está congestionada. Si su transacción no se procesa dentro de 2 minutos, repita la transacción.</string>
<string name="warning_solana_fee_title">Alerta de red Solana</string>
<string name="warning_solana_rent_fee_message">La red Solana cobra un alquiler de %1$s cada %2$s días. Las cuentas que no pueden pagar el alquiler son eliminadas de la red. Deposite en su cuenta más de 2 para usarla de forma gratuita.</string>
<string name="warning_some_networks_unreachable_message">Algunas redes no están disponibles actualmente. Por favor, inténtalo de nuevo más tarde.</string>
<string name="warning_some_networks_unreachable_message">Deslice hacia abajo para refrescar o inténtelo de nuevo más tarde.</string>
<string name="warning_some_networks_unreachable_title">Algunas redes no están disponibles</string>
<string name="warning_testnet_card_message">Esta es una tarjeta de Testnet. No puede procesar transacciones y solo deba usarse para pruebas y desarrollo.</string>
<string name="warning_testnet_card_title">Solo para fines de prueba</string>
@ -1084,7 +1087,7 @@
<string name="welcome_interrupted_backup_discard_resume">Reanudar backup</string>
<string name="welcome_interrupted_backup_discard_title">Esta es una acción irreversible</string>
<string name="welcome_unlock">Iniciar sesión con %s</string>
<string name="welcome_unlock_card">Escanee la tarjeta</string>
<string name="welcome_unlock_description">Use %s o escanee una tarjeta para acceder a la app</string>
<string name="welcome_unlock_card">Escanee la tarjeta o el anillo</string>
<string name="welcome_unlock_description">Use %s o escanee una tarjeta/anillo para acceder a la app</string>
<string name="welcome_unlock_title">¡Bienvenido de nuevo!</string>
</resources>

View file

@ -654,7 +654,7 @@
<string name="reset_card_with_backup_to_factory_message">La réinitialisation aux paramètres d\'usine supprimera complètement le portefeuille de la carte sélectionnée. Vous ne pourrez pas restaurer le portefeuille actuel ni utiliser la carte pour récupérer le code d\'accès.</string>
<string name="reset_card_without_backup_to_factory_message">La réinitialisation aux paramètres d\'usine supprimera complètement le portefeuille de la carte sélectionnée et le supprimera de l\'application. Vous ne pourrez pas restaurer le portefeuille actuel.</string>
<string name="ring_promo_text">Les propriétaires du Tangem Ring ont droit à 3 swap gratis sur Changelly jusqu\'au 15/11 !</string>
<string name="ring_promo_title">Échangez avec 0 %% de frais !</string>
<string name="ring_promo_title">Échangez avec 0 % de frais !</string>
<string name="save_user_wallet_agreement_access_description">Connectez-vous à l\'application et vérifiez votre solde sans scanner la carte</string>
<string name="save_user_wallet_agreement_access_title">Accéder à l\'application</string>
<string name="save_user_wallet_agreement_allow_biometrics">Autoriser l\'utilisation de la biométrie</string>
@ -912,6 +912,7 @@
<string name="token_swap_changelly_promotion_message">Échangez ce jeton contre un autre moyennant des frais de service de %1$s du %2$s au %3$s février.</string>
<string name="token_swap_changelly_promotion_title">Échangez avec Changelly, %s frais</string>
<string name="token_swap_promotion_button">Échangez maintenant</string>
<string name="tokens_list_hot_crypto_header">Crypto-monnaies populaire 🔥</string>
<string name="tokens_list_unavailable_to_purchase_header">Non disponible à l\'achat</string>
<string name="tokens_list_unavailable_to_sell_header">Indisponible à la vente</string>
<string name="tokens_list_unavailable_to_swap_header">Non disponible pour l\'échange de %s</string>
@ -993,7 +994,7 @@
<string name="wallet_network_group_title">%s réseau</string>
<string name="wallet_notification_address_copied">L\'adresse a été copiée avec succès</string>
<string name="wallet_notification_no_internet">Pas de connexion internet</string>
<string name="wallet_promo_banner_button_title">Obtenez-le maintenant avec 10%% de réduction</string>
<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_title">Paramètres du portefeuille</string>

View file

@ -86,6 +86,8 @@
<string name="cardano_max_amount_has_token_title">ADAが不足しています。</string>
<string name="common_accept">受け入れる</string>
<string name="common_access_denied">アクセスが拒否されました</string>
<string name="common_add_to_portfolio">ポートフォリオに追加</string>
<string name="common_add_token">トークンを追加</string>
<string name="common_all">すべて</string>
<string name="common_allow">許可する</string>
<string name="common_analytics">アナリティクス</string>
@ -335,6 +337,8 @@
<string name="give_permission_unlimited">無制限</string>
<string name="home_button_order">Tangemを注文</string>
<string name="home_button_scan">Tangemをスキャン</string>
<string name="hot_crypto_add_token_subtitle">%sへ</string>
<string name="hot_crypto_token_network">%s内</string>
<string name="information_generated_with_ai">この情報はAIで生成されました。 \nエラーが見つかった場合は、ここをタップしてください。</string>
<string name="initial_message_change_access_code_body">アクセスコードを変更するには、上図のようにカードまたはリングをタップし、操作が終了するまで取り外さないでください。</string>
<string name="initial_message_change_passcode_body">パスコードを変更するには、上記のようにカードをタップし、操作が終了するまで取り外さないでください。</string>
@ -644,7 +648,7 @@
<string name="reset_card_with_backup_to_factory_message">工場出荷時設定にリセットすると、選択したカードやリングからウォレットが完全に削除されます。現在のウォレットを復元したり、カードやリングを使用してアクセスコードを復元することはできません。</string>
<string name="reset_card_without_backup_to_factory_message">工場出荷時の状態にリセットすると、選択したカードやリングからウォレットが完全に削除され、アプリから削除されます。現在のウォレットを復元することはできません。</string>
<string name="ring_promo_text">Tangem Ringユーザーは、11/15日までChangelly経由でスワップを3回手数料ゼロで行えます</string>
<string name="ring_promo_title">今すぐ手数料0%%でスワップしましょう!</string>
<string name="ring_promo_title">今すぐ手数料0% でスワップしましょう!</string>
<string name="save_user_wallet_agreement_access_description">アプリにログインして、カードまたはリングをスキャンせずに残高を確認できます</string>
<string name="save_user_wallet_agreement_access_title">アプリにアクセスする</string>
<string name="save_user_wallet_agreement_allow_biometrics">生体認証の使用を許可する</string>
@ -776,6 +780,8 @@
<string name="staking_migrate">移行</string>
<string name="staking_native">ネイティブステーキング</string>
<string name="staking_no_validators_error_message">現在、ステーキングに使用できるアクティブなバリデータは見つかりません。しばらくしてからもう一度お試しください。</string>
<string name="staking_notification_additional_ada_deposit_text">Cardanoネットワークでステーキングする場合、残高全体が使用されます。追加の2ADAが予約され、ステーキング解除後に返却されます。ステーキング中はADAはロックされません。</string>
<string name="staking_notification_additional_ada_deposit_title">ADAステーキングの詳細</string>
<string name="staking_notification_claim_rewards_text">獲得した報酬はあなたのアドレスに直接送られ、すぐ使用可能です。</string>
<string name="staking_notification_earn_rewards_text">安全にステーキングして報酬を獲得しましょう</string>
<string name="staking_notification_earn_rewards_text_daily">安全にステーキングして、報酬を毎日獲得しましょう</string>
@ -902,6 +908,7 @@
<string name="token_swap_changelly_promotion_message">このトークンは、2月%2$s-%3$s の間、%1$s のサービス手数料で別のトークンと交換できます。</string>
<string name="token_swap_changelly_promotion_title">Changellyでスワップ、手数料%s</string>
<string name="token_swap_promotion_button">今すぐスワップ</string>
<string name="tokens_list_hot_crypto_header">ホットな暗号資産🔥</string>
<string name="tokens_list_unavailable_to_purchase_header">買付できません</string>
<string name="tokens_list_unavailable_to_sell_header">売却できません</string>
<string name="tokens_list_unavailable_to_swap_header">%sからのスワップは利用できません</string>
@ -935,7 +942,7 @@
<string name="user_push_notification_agreement_argument_two">新しいプロモーション情報をいち早く入手しましょう</string>
<string name="user_push_notification_agreement_header">プッシュ通知を使用しますか?</string>
<string name="user_wallet_list_add_button">新しいウォレットを追加</string>
<string name="user_wallet_list_delete_prompt">本当にこのウォレットを削除してもよろしいですか?</string>
<string name="user_wallet_list_delete_prompt">このウォレットを忘れてもよろしいですか?</string>
<string name="user_wallet_list_error_unable_to_unlock">エラーが発生しました。カードまたはリングをスキャンしてログインしてください。</string>
<string name="user_wallet_list_error_wallet_already_saved">このウォレットはすでに保存されています。別のウォレットを追加できます。</string>
<string name="user_wallet_list_rename_popup_error_already_exists">%sという名前のウォレットはすでに存在します。</string>
@ -983,7 +990,7 @@
<string name="wallet_network_group_title">%sネットワーク</string>
<string name="wallet_notification_address_copied">アドレスがクリップボードにコピーされました</string>
<string name="wallet_notification_no_internet">インターネット接続がありません</string>
<string name="wallet_promo_banner_button_title">今すぐ10 %%オフで購入</string>
<string name="wallet_promo_banner_button_title">今すぐ10 % オフで購入</string>
<string name="wallet_promo_banner_description">1.3万種類以上の暗号資産にアクセス。ワンタップで買付、売却、スワップ、ステーキングが可能です。\nバックアップ用に最大3枚のカードを連携できます。</string>
<string name="wallet_promo_banner_title">Tangemウォレットを見る</string>
<string name="wallet_settings_title">ウォレット設定</string>
@ -1034,6 +1041,7 @@
<string name="warning_kaspa_unfinished_token_transaction_discard_message">取引をキャンセルしてもよろしいですか? 取引を再試行することはできません</string>
<string name="warning_kaspa_unfinished_token_transaction_message">%1$s %2$sの取引が完了しませんでした。もう一度試して完了してください。</string>
<string name="warning_kaspa_unfinished_token_transaction_title">未完了の取引があります</string>
<string name="warning_last_balance_updated_time">最終更新日は%sです</string>
<string name="warning_low_signatures_message">このカードには%sの署名のみが残っています。資金をすべて引き出す必要があります。</string>
<string name="warning_low_signatures_title">署名数が少ないです</string>
<string name="warning_manage_tokens_legacy_derivation_message">異なるネットワーク上のトークンは、異なるアドレスを持つ場合があります。資金を送金する際には、アドレスがネットワークと一致していることを再確認してください。</string>
@ -1054,6 +1062,10 @@
<string name="warning_rate_app_title">Tangemを楽しんでいますか?</string>
<string name="warning_receive_blocked_hedera_token_association_required_message">トークンを受け取る前に、トークンを関連付ける必要があります。</string>
<string name="warning_rent_fee_title">ネットワーク使用料が必要です</string>
<string name="warning_seedphrase_issue_answer_no">ありがとうございます。準備完了です。これ以上の操作は必要ありません。</string>
<string name="warning_seedphrase_issue_answer_yes">Tangemの公式ウェブサイトに移動します。そちらの指示に従ってください。</string>
<string name="warning_seedphrase_issue_message">このアプリ経由でTangemサポートチームに直接連絡したことがありますか</string>
<string name="warning_seedphrase_issue_title">必須のセキュリティアップデート</string>
<string name="warning_send_blocked_funds_for_fee_message">%1$s は %2$s ネットワーク内のアセットです。%3$s 取引を行うには、ネットワーク手数料のために %4$s (%5$s) を入金する必要があります。</string>
<string name="warning_send_blocked_funds_for_fee_title">ネットワーク料金をカバーするための%1$sが足りません</string>
<string name="warning_solana_fee_message">Solanaネットワークが混雑しています。2分以内に取引が完了しない場合は、再度取引を繰り返してください。</string>
@ -1061,6 +1073,7 @@
<string name="warning_solana_rent_fee_message">Solana ネットワークは 2 日ごとに%1$sのレンタル料を請求します。レンタル料を支払えないアカウントはネットワークから削除されます。アカウントに%2$s以上入金すると、無料で使用できます。</string>
<string name="warning_some_networks_unreachable_message">下にスワイプして更新するか、後でもう一度お試しください。</string>
<string name="warning_some_networks_unreachable_title">一部のネットワークにアクセスできません</string>
<string name="warning_some_token_balances_not_updated">一部のトークン残高を更新できませんでした</string>
<string name="warning_testnet_card_message">これはテストネットカードです。取引処理はできませんので、テストおよび開発目的でのみご利用ください。</string>
<string name="warning_testnet_card_title">テスト目的のみ</string>
<string name="welcome_interrupted_backup_alert_discard">破棄</string>

View file

@ -672,7 +672,7 @@
<string name="reset_card_with_backup_to_factory_message">Сброс к заводским настройкам приведет к полному удалению кошелька с выбранной карты или кольца. Вы не сможете восстановить текущий кошелек или использовать данную карту или кольцо для восстановления кода доступа.</string>
<string name="reset_card_without_backup_to_factory_message">Сброс к заводским настройкам приведет к полному удалению кошелька с выбранной карты или кольца. Вы не сможете восстановить текущий кошелек.</string>
<string name="ring_promo_text">Владельцам колец — 3 обмена без комиссии на Changelly до 15.11!</string>
<string name="ring_promo_title">Обмен с 0%% комиссией!</string>
<string name="ring_promo_title">Обмен с 0% комиссией!</string>
<string name="save_user_wallet_agreement_access_description">Войдите в приложение и следите за своим балансом без сканирования карты или кольца</string>
<string name="save_user_wallet_agreement_access_title">Доступ в приложение</string>
<string name="save_user_wallet_agreement_allow_biometrics">Использовать биометрию</string>
@ -929,6 +929,7 @@
<string name="token_swap_changelly_promotion_message">Обменивайте этот токен на другие с %1$s комиссии за обслуживание с %2$s по %3$s февраля.</string>
<string name="token_swap_changelly_promotion_title">Обмен с Changelly, %s комиссии</string>
<string name="token_swap_promotion_button">Обменять</string>
<string name="tokens_list_hot_crypto_header">В тренде🔥</string>
<string name="tokens_list_unavailable_to_purchase_header">Недоступно для покупки</string>
<string name="tokens_list_unavailable_to_sell_header">Недоступно для продажи</string>
<string name="tokens_list_unavailable_to_swap_header">Недоступно для обмена с %s</string>
@ -962,7 +963,7 @@
<string name="user_push_notification_agreement_argument_two">Узнавайте первым о новых акциях</string>
<string name="user_push_notification_agreement_header">Хотите использовать Push-уведомления?</string>
<string name="user_wallet_list_add_button">Добавить новый кошелек</string>
<string name="user_wallet_list_delete_prompt">Вы уверены, что хотите удалить этот кошелек?</string>
<string name="user_wallet_list_delete_prompt">Вы уверены, что хотите забыть этот кошелек?</string>
<string name="user_wallet_list_error_unable_to_unlock">Произошла ошибка, пожалуйста, отсканируйте свою карту или кольцо для входа</string>
<string name="user_wallet_list_error_wallet_already_saved">Этот кошелек уже был сохранен, вы можете добавить другой</string>
<string name="user_wallet_list_rename_popup_error_already_exists">Кошелек с именем %s уже существует</string>
@ -1010,7 +1011,7 @@
<string name="wallet_network_group_title">Сеть %s</string>
<string name="wallet_notification_address_copied">Адрес скопирован в буфер обмена</string>
<string name="wallet_notification_no_internet">Нет соединения с интернетом</string>
<string name="wallet_promo_banner_button_title">Получить с 10%% скидкой</string>
<string name="wallet_promo_banner_button_title">Получить с 10% скидкой</string>
<string name="wallet_promo_banner_description">Получите доступ к более чем 13 000 криптовалют. Покупайте, продавайте, обменивайте и стейкайте в один клик. Свяжите до трех карт для резервного копирования. </string>
<string name="wallet_promo_banner_title">Откройте Tangem Wallet</string>
<string name="wallet_settings_title">Настройки кошелька</string>

View file

@ -51,6 +51,8 @@
<string name="balance_hidden_do_not_show_button">Більше не показувати</string>
<string name="balance_hidden_got_it_button">Зрозуміло</string>
<string name="balance_hidden_title">Баланси приховані</string>
<string name="beta_mode_warning_message">Згідно інформації від розробників мережі, токени Kaspa знаходяться у режимі бета. Слідкуйте за оновленнями!</string>
<string name="beta_mode_warning_title">Бета режим</string>
<string name="biometric_lockout_permanent_warning_description">Будь ласка, відскануйте картку або кільце</string>
<string name="biometric_lockout_warning_description">Будь ласка, спробуйте знову через 30 секунд або відскануйте картку або кільце</string>
<string name="biometric_lockout_warning_title">Забагато спроб</string>
@ -672,7 +674,7 @@
<string name="reset_card_with_backup_to_factory_message">Скидання до заводських налаштувань призведе до повного видалення гаманця з обраної картки або кільця. Ви не зможете відновити поточний гаманець або використати цю картку або кільце для відновлення коду доступу.</string>
<string name="reset_card_without_backup_to_factory_message">Скидання до заводських налаштувань призведе до повного видалення гаманця з обраної картки або кільця. Ви не зможете відновити поточний гаманець.</string>
<string name="ring_promo_text">Власникам кілець - 3 обміни без комісії на Changelly до 15.11!</string>
<string name="ring_promo_title">Обмін з 0%% комісією!</string>
<string name="ring_promo_title">Обмін з 0% комісією!</string>
<string name="save_user_wallet_agreement_access_description">Увійдіть у додаток та слідкуйте за своїм балансом без сканування картки чи кільця</string>
<string name="save_user_wallet_agreement_access_title">Доступ до додатку</string>
<string name="save_user_wallet_agreement_allow_biometrics">Використовувати біометрію</string>
@ -930,6 +932,7 @@
<string name="token_swap_changelly_promotion_message">Обмінюйте цей токен на інші з %1$s комісією за обслуговування з %2$s по %3$s лютого.</string>
<string name="token_swap_changelly_promotion_title">Обмін із Changelly, %s комісії</string>
<string name="token_swap_promotion_button">Обміняти</string>
<string name="tokens_list_hot_crypto_header">В тренді 🔥</string>
<string name="tokens_list_unavailable_to_purchase_header">Недоступно для покупки</string>
<string name="tokens_list_unavailable_to_sell_header">Недоступно для продажу</string>
<string name="tokens_list_unavailable_to_swap_header">Недоступно для обміну з %s</string>
@ -1011,7 +1014,7 @@
<string name="wallet_network_group_title">Мережа %s</string>
<string name="wallet_notification_address_copied">Адреса скопійована в буфер обміну</string>
<string name="wallet_notification_no_internet">Немає підключення до інтернету</string>
<string name="wallet_promo_banner_button_title">Отримати з 10%% знижкою</string>
<string name="wallet_promo_banner_button_title">Отримати з 10% знижкою</string>
<string name="wallet_promo_banner_description">Доступ до 13,000+ криптовалют. Купуйте, продавайте, обмінюйте та стейкайте одним дотиком.\nЗєднайте до трьох карток для бекапу.</string>
<string name="wallet_promo_banner_title">Відкрийте Tangem Wallet</string>
<string name="wallet_settings_title">Налаштування гаманця</string>

View file

@ -87,6 +87,8 @@
<string name="cardano_max_amount_has_token_title">Not enough ADA</string>
<string name="common_accept">Accept</string>
<string name="common_access_denied">Access denied</string>
<string name="common_add_to_portfolio">Add to portfolio</string>
<string name="common_add_token">Add token</string>
<string name="common_all">All</string>
<string name="common_allow">Allow</string>
<string name="common_analytics">Analytics</string>
@ -140,6 +142,7 @@
<string name="common_generate_addresses">Synchronize addresses</string>
<string name="common_go_to_provider">Go to provider</string>
<string name="common_go_to_token">Go to token</string>
<string name="common_hide">Hide</string>
<string name="common_hour">hour</string>
<string name="common_import">Import</string>
<string name="common_in_progress">In progress</string>
@ -312,6 +315,9 @@
<string name="express_status_bought">Bought %s</string>
<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_title">Hide Transaction Status?</string>
<string name="express_token_list_empty_search">No tokens found. Please try another request</string>
<string name="express_transaction_id">ID: %s</string>
<string name="express_transaction_id_copied">Transaction ID copied</string>
@ -338,6 +344,8 @@
<string name="give_permission_unlimited">Unlimited</string>
<string name="home_button_order">Order Tangem</string>
<string name="home_button_scan">Scan Tangem</string>
<string name="hot_crypto_add_token_subtitle">to %s</string>
<string name="hot_crypto_token_network">In %s</string>
<string name="information_generated_with_ai">This information was generated with AI.\nTap here, if you find any errors.</string>
<string name="initial_message_change_access_code_body">To change the access code tap the card or ring as shown above and do not remove until the end of the operation</string>
<string name="initial_message_change_passcode_body">To change the passcode tap the card as shown above and do not remove until the end of the operation</string>
@ -654,7 +662,7 @@
<string name="reset_card_with_backup_to_factory_message">Factory Reset will completely delete the wallet from the selected card or ring. You will not be able to restore the current wallet or use the card or ring to recover the access code.</string>
<string name="reset_card_without_backup_to_factory_message">Factory Reset will completely delete the wallet from the selected card or ring and remove it from the app. You will not be able to restore the current wallet.</string>
<string name="ring_promo_text">Ring owners get 3 commission-free swaps on Changelly until 15.11!</string>
<string name="ring_promo_title">Swap With 0%% Fees Now!</string>
<string name="ring_promo_title">Swap With 0% Fees Now!</string>
<string name="save_user_wallet_agreement_access_description">Log into the app and check your balance without scanning the card or ring</string>
<string name="save_user_wallet_agreement_access_title">Access the app</string>
<string name="save_user_wallet_agreement_allow_biometrics">Allow to use biometrics</string>
@ -786,6 +794,8 @@
<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>
<string name="staking_notification_additional_ada_deposit_text">When staking in the Cardano network, the entire balance is used. An additional 2 ADA will be reserved and returned after unstaking. Your ADA is not locked while staking.</string>
<string name="staking_notification_additional_ada_deposit_title">ADA Staking Details</string>
<string name="staking_notification_claim_rewards_text">Earned rewards will be sent to your wallet and available for use immediately</string>
<string name="staking_notification_earn_rewards_text">Stake securely and start earning your rewards</string>
<string name="staking_notification_earn_rewards_text_daily">Stake securely and start earning daily rewards</string>
@ -799,6 +809,8 @@
<string name="staking_notification_earn_rewards_title">Earn staking rewards</string>
<string name="staking_notification_low_staked_balance_text">Your remaining staked balance will be too low to unstake. Youll need to stake more to meet the minimum unstake amount.</string>
<string name="staking_notification_low_staked_balance_title">Low staked balance</string>
<string name="staking_notification_minimum_balance_error_text">A minimum of %1$s %2$s is required for restaking. Please top up your balance.</string>
<string name="staking_notification_minimum_balance_error_title">Not enough %s</string>
<string name="staking_notification_network_error_text">Staking is currently unavailable due to network conditions. Please try again later.</string>
<string name="staking_notification_new_validator_funds_transfer">Staking in the %1$s network with a new validator will automatically transfer all previously staked funds to this validator</string>
<string name="staking_notification_restake_rewards_text">Reinvests your earned rewards in your staked amount, increasing potential earnings.</string>
@ -912,6 +924,7 @@
<string name="token_swap_changelly_promotion_message">Exchange this token for another at %1$s service fees from February %2$s-%3$s.</string>
<string name="token_swap_changelly_promotion_title">Swap with Changelly, %s fees</string>
<string name="token_swap_promotion_button">Swap now</string>
<string name="tokens_list_hot_crypto_header">Hot crypto 🔥</string>
<string name="tokens_list_unavailable_to_purchase_header">Unavailable to purchase</string>
<string name="tokens_list_unavailable_to_sell_header">Unavailable to sell</string>
<string name="tokens_list_unavailable_to_swap_header">Unavailable for swap from %s</string>
@ -945,7 +958,7 @@
<string name="user_push_notification_agreement_argument_two">Be the first to know about new promotions</string>
<string name="user_push_notification_agreement_header">Would you like to use\nPush-notifications?</string>
<string name="user_wallet_list_add_button">Add new wallet</string>
<string name="user_wallet_list_delete_prompt">Are you sure you want to delete this wallet?</string>
<string name="user_wallet_list_delete_prompt">Are you sure you want to forget this wallet?</string>
<string name="user_wallet_list_error_unable_to_unlock">An error has occurred, please scan your card or ring to log in</string>
<string name="user_wallet_list_error_wallet_already_saved">This wallet has already been saved, you can add another one</string>
<string name="user_wallet_list_rename_popup_error_already_exists">The wallet with name %s already exists</string>
@ -955,7 +968,7 @@
<string name="user_wallet_list_unlock_all_with">Unlock all with %s</string>
<string name="wallet_balance_blockchain_unreachable_try_later">Blockchain is unreachable. Try later</string>
<string name="wallet_balance_missing_derivation">Scan card or ring</string>
<string name="wallet_been_activated_message">This wallet has already been activated earlier.\nIf it was done not by you please contact support.\nTangem never sells wallets along with the pre-generated access code.</string>
<string name="wallet_been_activated_message">This wallet has already been activated earlier.\nIf it was not done by you, please contact support.\nTangem never sells wallets along with pre-generated access codes.</string>
<string name="wallet_connect_alert_sign_message">Requesting to sign a message.\n\n%s</string>
<string name="wallet_connect_bnb_sign_message">Dapp %1$s, requesting to\nsign BNB transaction.\n\n%2$s</string>
<string name="wallet_connect_bnb_trade_order_message">Trade order for %1$s\nPrice: %2$s\nAmount to receive: %3$s\nAmount to pay: %4$s</string>
@ -993,7 +1006,7 @@
<string name="wallet_network_group_title">%s network</string>
<string name="wallet_notification_address_copied">Address was copied to clipboard</string>
<string name="wallet_notification_no_internet">No internet connection</string>
<string name="wallet_promo_banner_button_title">Get now with 10%% off</string>
<string name="wallet_promo_banner_button_title">Get now with 10% off</string>
<string name="wallet_promo_banner_description">Access 13,000+ cryptocurrencies. Buy, sell, swap, and stake with a single tap.\nLink up to three cards for a backup.</string>
<string name="wallet_promo_banner_title">Discover Tangem Wallet</string>
<string name="wallet_settings_title">Wallet settings</string>
@ -1044,6 +1057,7 @@
<string name="warning_kaspa_unfinished_token_transaction_discard_message">Are you sure you want to cancel the transaction? You will not be able to retry the transaction again</string>
<string name="warning_kaspa_unfinished_token_transaction_message">Your transaction with an amount of %1$s %2$s was not completed. You can try again to complete it.</string>
<string name="warning_kaspa_unfinished_token_transaction_title">You have unfinished transaction</string>
<string name="warning_last_balance_updated_time">Last update was %s</string>
<string name="warning_low_signatures_message">Only %s signatures are left on this card. You must withdraw all of your funds.</string>
<string name="warning_low_signatures_title">Low signature count</string>
<string name="warning_manage_tokens_legacy_derivation_message">Tokens on different networks can have different addresses. Double-check that your address matches the network when you transfer funds.</string>
@ -1076,6 +1090,7 @@
<string name="warning_solana_rent_fee_message">Solana network charges a rent of %1$s every 2 days. Accounts that can\'t afford the rent are purged from the network. Deposit your account with more than %2$s to use it for free.</string>
<string name="warning_some_networks_unreachable_message">Swipe down to refresh or try again later.</string>
<string name="warning_some_networks_unreachable_title">Some networks are unreachable</string>
<string name="warning_some_token_balances_not_updated">Some token balances could not be updated</string>
<string name="warning_testnet_card_message">This is a Testnet card. It cannot process transactions and should only be used for testing and development purposes.</string>
<string name="warning_testnet_card_title">For testing purposes only</string>
<string name="welcome_interrupted_backup_alert_discard">Discard</string>

View file

@ -89,7 +89,7 @@ class CryptoCurrencyFactory(
return CryptoCurrency.Coin(
id = getCoinId(network, blockchain.toCoinId()),
network = network,
name = blockchain.fullName,
name = blockchain.getCoinName(),
symbol = blockchain.currency,
iconUrl = getCoinIconUrl(blockchain),
decimals = blockchain.decimals(),

View file

@ -30,7 +30,7 @@ fun getNetwork(
return Network(
id = Network.ID(blockchain.id),
backendId = blockchain.toNetworkId(),
name = blockchain.getNetworkName(),
name = blockchain.fullName,
isTestnet = blockchain.isTestnet(),
derivationPath = getNetworkDerivationPath(
blockchain = blockchain,
@ -59,7 +59,7 @@ fun getNetwork(
return Network(
id = networkId,
backendId = blockchain.toNetworkId(),
name = blockchain.getNetworkName(),
name = blockchain.fullName,
isTestnet = blockchain.isTestnet(),
derivationPath = derivationPath,
currencySymbol = blockchain.currency,

View file

@ -2,7 +2,6 @@ package com.tangem.data.common.currency
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.Token
import com.tangem.blockchainsdk.compatibility.l2BlockchainsList
import com.tangem.blockchainsdk.utils.ExcludedBlockchains
import com.tangem.blockchainsdk.utils.fromNetworkId
import com.tangem.blockchainsdk.utils.toCoinId
@ -78,7 +77,7 @@ class ResponseCryptoCurrenciesFactory(
return CryptoCurrency.Coin(
id = getCoinId(network, blockchain.toCoinId()),
network = network,
name = blockchain.getNameForCoin(responseToken),
name = blockchain.getCoinName(),
symbol = blockchain.getSymbolForCoin(responseToken),
decimals = responseToken.decimals,
iconUrl = getCoinIconUrl(blockchain),
@ -86,21 +85,6 @@ class ResponseCryptoCurrenciesFactory(
)
}
private fun Blockchain.getNameForCoin(responseToken: UserTokensResponse.Token): String {
return when (this) {
// workaround: for Blockchains full name different than backend name,
// get name and symbol from enum Blockchain until backend renamed
// [REDACTED_JIRA]
Blockchain.Dischain,
Blockchain.Telos,
Blockchain.Cronos,
Blockchain.TON,
in l2BlockchainsList,
-> this.fullName
else -> responseToken.name
}
}
private fun Blockchain.getSymbolForCoin(responseToken: UserTokensResponse.Token): String {
return when (this) {
// workaround: Dischain was renamed but backend still returns the old name,

View file

@ -295,7 +295,7 @@ internal class DefaultManageTokensRepository(
)
return if (!canHandleBlockchain) {
CurrencyUnsupportedState.UnsupportedNetwork(networkName = blockchain.getNetworkName())
CurrencyUnsupportedState.UnsupportedNetwork(networkName = blockchain.fullName)
} else {
null
}
@ -314,10 +314,10 @@ internal class DefaultManageTokensRepository(
return when {
// refactor this later by moving all this logic in card config
blockchain == Blockchain.Solana && !supportedTokens.contains(Blockchain.Solana) -> {
CurrencyUnsupportedState.Token.NetworkTokensUnsupported(networkName = blockchain.getNetworkName())
CurrencyUnsupportedState.Token.NetworkTokensUnsupported(networkName = blockchain.fullName)
}
!userWallet.scanResponse.card.canHandleToken(supportedTokens, blockchain, cardTypesResolver) -> {
CurrencyUnsupportedState.Token.UnsupportedCurve(networkName = blockchain.getNetworkName())
CurrencyUnsupportedState.Token.UnsupportedCurve(networkName = blockchain.fullName)
}
else -> null
}

View file

@ -32,7 +32,7 @@ internal object CoinsResponseConverter : Converter<CoinsData, List<Token>> {
Token.Network(
networkId = network.networkId,
standardType = getNetworkStandardType(blockchain).name,
name = blockchain.getNetworkName(),
name = blockchain.fullName,
address = network.contractAddress,
iconUrl = getIconUrl(network.networkId, value.imageHost),
decimalCount = network.decimalCount?.toInt(),

View file

@ -10,6 +10,7 @@ interface ScanCardProcessor {
suspend fun scan(
cardId: String? = null,
allowsRequestAccessCodeFromRepository: Boolean = false,
analyticsSource: AnalyticsParam.ScreensSources,
): CompletionResult<ScanResponse>
suspend fun scan(

View file

@ -7,12 +7,35 @@ import arrow.core.raise.either
import com.tangem.domain.tokens.error.CurrencyStatusError
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.tokens.repository.CurrenciesRepository
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.domain.wallets.models.UserWalletId
class GetCryptoCurrencyUseCase(
private val currenciesRepository: CurrenciesRepository,
) {
/**
* Returns specific cryptocurrency for a given user wallet.
*
* !!! Important Use only [CryptoCurrency.ID.value] as cryptoCurrencyId
*
* @param userWallet The user's wallet.
* @param cryptoCurrencyId The ID of the cryptocurrency.
* @return An [Either] representing success (Right) or an error (Left) in fetching the status.
*/
suspend operator fun invoke(
userWallet: UserWallet,
cryptoCurrencyId: String,
): Either<CurrencyStatusError, CryptoCurrency> {
return either {
if (userWallet.isMultiCurrency) {
getCurrency(userWallet.walletId, cryptoCurrencyId)
} else {
getPrimaryCurrency(userWallet.walletId)
}
}
}
/**
* Returns specific cryptocurrency for a given user wallet.
*

View file

@ -19,7 +19,7 @@ class GetCurrencyCheckUseCase(
currencyStatus: CryptoCurrencyStatus,
amount: BigDecimal?,
fee: BigDecimal?,
balanceAfterTransaction: BigDecimal?,
feeCurrencyBalanceAfterTransaction: BigDecimal?,
recipientAddress: String? = null,
): CryptoCurrencyCheck {
return withContext(dispatchers.io) {
@ -32,7 +32,7 @@ class GetCurrencyCheckUseCase(
val rentWarning = currencyChecksRepository.getRentExemptionError(
userWalletId = userWalletId,
currencyStatus = currencyStatus,
balanceAfterTransaction = balanceAfterTransaction ?: BigDecimal.ZERO,
balanceAfterTransaction = feeCurrencyBalanceAfterTransaction ?: BigDecimal.ZERO,
)
val isAccountFunded = recipientAddress?.let {
currencyChecksRepository.checkIfAccountFunded(

View file

@ -5,6 +5,7 @@ import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.tangem.common.CompletionResult
import com.tangem.common.core.TangemSdkError
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.core.analytics.models.event.OnboardingAnalyticsEvent
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.model.Model
@ -246,7 +247,9 @@ class MultiWalletBackupModel @Inject constructor(
}
private fun showCardVerificationFailedDialog(error: TangemSdkError.CardVerificationFailed) {
analyticsEventHandler.send(event = OnboardingAnalyticsEvent.Onboarding.OfflineAttestationFailed)
analyticsEventHandler.send(
event = OnboardingAnalyticsEvent.Onboarding.OfflineAttestationFailed(AnalyticsParam.ScreensSources.Backup),
)
val resource = error.localizedDescriptionRes()
val resId = resource.resId ?: com.tangem.core.ui.R.string.common_unknown_error

View file

@ -95,20 +95,19 @@ internal class SendNotificationFactory(
val feeError = (feeState.feeSelectorState as? FeeSelectorState.Error)?.error
val recipientAddress = state.recipientState?.addressTextField?.value
val statusValue = cryptoCurrencyStatus.value as? CryptoCurrencyStatus.Loaded
val feeToSubtract = if (isSubtractAvailableProvider()) {
feeValue
} else {
BigDecimal.ZERO
}
val balanceAfterTransaction = statusValue?.let { it.amount - sendingAmount - feeToSubtract }
val feeCurrencyBalanceAfterTransaction = getFeeCurrencyBalanceAfterTx(
feeCurrencyStatus = feeCryptoCurrencyStatusProvider(),
sendingCurrencyStatus = cryptoCurrencyStatus,
sendingAmount = sendingAmount,
feeValue = feeValue,
)
val currencyCheck = getCurrencyCheckUseCase(
userWalletId = userWalletId,
currencyStatus = cryptoCurrencyStatus,
amount = sendingAmount,
fee = feeValue,
recipientAddress = recipientAddress,
balanceAfterTransaction = balanceAfterTransaction,
feeCurrencyBalanceAfterTransaction = feeCurrencyBalanceAfterTransaction,
)
buildList {
addErrorNotifications(
@ -143,6 +142,23 @@ internal class SendNotificationFactory(
)
}
private fun getFeeCurrencyBalanceAfterTx(
feeCurrencyStatus: CryptoCurrencyStatus?,
sendingCurrencyStatus: CryptoCurrencyStatus,
sendingAmount: BigDecimal,
feeValue: BigDecimal,
): BigDecimal? {
val sendingCurrencyBalance = sendingCurrencyStatus.value as? CryptoCurrencyStatus.Loaded
val feeCurrencyBalance = feeCurrencyStatus?.value as? CryptoCurrencyStatus.Loaded
if (feeCurrencyStatus?.value !is CryptoCurrencyStatus.Loaded) return null
return when {
feeCurrencyStatus == sendingCurrencyStatus -> sendingCurrencyBalance?.let {
it.amount - sendingAmount - feeValue
}
else -> feeCurrencyBalance?.let { it.amount - feeValue }
}
}
private suspend fun MutableList<NotificationUM>.addErrorNotifications(
feeError: GetFeeError?,
sendingAmount: BigDecimal,

View file

@ -16,6 +16,7 @@ import com.tangem.domain.staking.model.stakekit.action.StakingActionCommonType
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.features.staking.impl.R
import com.tangem.lib.crypto.BlockchainUtils.isTron
import com.tangem.utils.isNullOrZero
import com.tangem.utils.transformer.Transformer
import java.math.BigDecimal
import java.math.RoundingMode
@ -41,8 +42,16 @@ internal class AmountRequirementStateTransformer(
val isIntegerOnlyError = isIntegerOnlyError(amountState, actionType)
val cryptoAmount = amountState.amountTextField.cryptoAmount
val roundedDownCrypto = cryptoAmount.value?.setScale(0, RoundingMode.DOWN)
val value = roundedDownCrypto?.parseBigDecimal(0).orEmpty()
val roundedDownCrypto = cryptoAmount.value
?.setScale(0, RoundingMode.DOWN)
?.parseBigDecimal(0)
.orEmpty()
val isAmountZeroOrNull = if (amountState.amountTextField.isFiatValue) {
amountState.amountTextField.fiatAmount.value.isNullOrZero()
} else {
amountState.amountTextField.cryptoAmount.value.isNullOrZero()
}
val errorText = when {
amountState.amountTextField.isError -> amountState.amountTextField.error
@ -50,11 +59,11 @@ internal class AmountRequirementStateTransformer(
isIntegerOnlyError -> when (actionType) {
StakingActionCommonType.Enter -> resourceReference(
R.string.staking_amount_tron_integer_error,
wrappedList(value),
wrappedList(roundedDownCrypto),
)
StakingActionCommonType.Exit -> resourceReference(
R.string.staking_amount_tron_integer_error_unstaking,
wrappedList(value),
wrappedList(roundedDownCrypto),
)
else -> null
}
@ -62,7 +71,7 @@ internal class AmountRequirementStateTransformer(
}
val isError = amountState.amountTextField.isError || requirementError != null
return amountState.copy(
isPrimaryButtonEnabled = !isError,
isPrimaryButtonEnabled = !isAmountZeroOrNull && !isError,
amountTextField = amountState.amountTextField.copy(
isError = isError,
isWarning = isIntegerOnlyError,

View file

@ -647,7 +647,7 @@ internal class StakingViewModel @Inject constructor(
currencyStatus = cryptoCurrencyStatus,
amount = amount,
fee = fee,
balanceAfterTransaction = balanceAfterTransaction,
feeCurrencyBalanceAfterTransaction = balanceAfterTransaction,
)
stateController.update(
AddStakingNotificationsTransformer(
@ -850,13 +850,11 @@ internal class StakingViewModel @Inject constructor(
)
getCurrencyStatusUpdatesUseCase(userWalletId, cryptoCurrencyId, false)
.conflate()
.distinctUntilChanged()
.distinctUntilChangedBy { it.getOrNull()?.value?.yieldBalance }
.filter { value.currentStep == StakingStep.InitialInfo }
.onEach { maybeStatus ->
maybeStatus.fold(
ifRight = { status ->
if (status.value !is CryptoCurrencyStatus.Loaded) return@fold
if (!isInitialInfoAnalyticSent) {
isInitialInfoAnalyticSent = true
val balances = status.value.yieldBalance as? YieldBalance.Data

View file

@ -409,7 +409,7 @@ internal class SwapInteractorImpl @AssistedInject constructor(
currencyStatus = fromTokenStatus,
amount = amount.value,
fee = fee,
balanceAfterTransaction = balanceAfterTransaction,
feeCurrencyBalanceAfterTransaction = balanceAfterTransaction,
)
return currencyCheck

View file

@ -68,7 +68,7 @@ internal class WalletDeepLinksHandler @Inject constructor(
}
private suspend fun onSellCurrencyDeepLink(userWallet: UserWallet, data: SellCurrencyDeepLink.Data) {
val cryptoCurrency = getCryptoCurrencyUseCase(userWallet.walletId, data.currencyId).getOrNull()
val cryptoCurrency = getCryptoCurrencyUseCase(userWallet, data.currencyId).getOrNull()
if (cryptoCurrency == null) {
Timber.e("onSellCurrencyDeepLink cryptoCurrency is null")

View file

@ -5,6 +5,7 @@ import arrow.core.raise.either
import arrow.core.raise.ensure
import com.tangem.common.CompletionResult
import com.tangem.common.core.TangemSdkError
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.domain.card.ScanCardProcessor
import com.tangem.domain.wallets.builder.UserWalletBuilder
import com.tangem.domain.wallets.usecase.GenerateWalletNameUseCase
@ -22,7 +23,7 @@ internal class ScanCardToUnlockWalletClickHandler @Inject constructor(
suspend operator fun invoke(walletId: UserWalletId): Either<ScanCardToUnlockWalletError, Unit> {
return either {
when (val result = scanCardProcessor.scan()) {
when (val result = scanCardProcessor.scan(analyticsSource = AnalyticsParam.ScreensSources.Main)) {
is CompletionResult.Failure -> {
if (result.error is TangemSdkError.UserCancelled) {
scanFailsCounter++

View file

@ -1,32 +0,0 @@
package com.tangem.feature.wallet.presentation.wallet.state.transformers
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState
import timber.log.Timber
internal class RenameWalletTransformer(
userWalletId: UserWalletId,
private val newName: String,
) : WalletStateTransformer(userWalletId) {
override fun transform(prevState: WalletState): WalletState {
return when (prevState) {
is WalletState.MultiCurrency.Content -> {
prevState.copy(walletCardState = prevState.walletCardState.copySealed(title = newName))
}
is WalletState.SingleCurrency.Content -> {
prevState.copy(walletCardState = prevState.walletCardState.copySealed(title = newName))
}
is WalletState.Visa.Content -> {
prevState.copy(walletCardState = prevState.walletCardState.copySealed(title = newName))
}
is WalletState.MultiCurrency.Locked,
is WalletState.SingleCurrency.Locked,
is WalletState.Visa.Locked,
-> {
Timber.e("Impossible to rename wallet in locked state")
prevState
}
}
}
}

View file

@ -0,0 +1,53 @@
package com.tangem.feature.wallet.presentation.wallet.state.transformers
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletScreenState
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState
import kotlinx.collections.immutable.toImmutableList
import timber.log.Timber
/**
* Transformer that renames wallets
*
* @property renamedWallets renamed wallets
*/
internal class RenameWalletsTransformer(
private val renamedWallets: List<UserWallet>,
) : WalletScreenStateTransformer {
override fun transform(prevState: WalletScreenState): WalletScreenState {
return prevState.copy(
wallets = prevState.wallets.map { walletState ->
val renamedWallet = renamedWallets.firstOrNull { it.walletId == walletState.walletCardState.id }
if (renamedWallet != null) {
transform(prevState = walletState, newName = renamedWallet.name)
} else {
walletState
}
}
.toImmutableList(),
)
}
private fun transform(prevState: WalletState, newName: String): WalletState {
return when (prevState) {
is WalletState.MultiCurrency.Content -> {
prevState.copy(walletCardState = prevState.walletCardState.copySealed(title = newName))
}
is WalletState.SingleCurrency.Content -> {
prevState.copy(walletCardState = prevState.walletCardState.copySealed(title = newName))
}
is WalletState.Visa.Content -> {
prevState.copy(walletCardState = prevState.walletCardState.copySealed(title = newName))
}
is WalletState.MultiCurrency.Locked,
is WalletState.SingleCurrency.Locked,
is WalletState.Visa.Locked,
-> {
Timber.e("Impossible to rename wallet in locked state")
prevState
}
}
}
}

View file

@ -308,8 +308,8 @@ internal class WalletViewModel @Inject constructor(
),
)
}
is WalletsUpdateActionResolver.Action.UpdateWalletName -> {
stateHolder.update(transformer = RenameWalletTransformer(action.selectedWalletId, action.name))
is WalletsUpdateActionResolver.Action.RenameWallets -> {
stateHolder.update(transformer = RenameWalletsTransformer(renamedWallets = action.renamedWallets))
}
is WalletsUpdateActionResolver.Action.Unknown -> {
Timber.w("Unable to perform action: $action")

View file

@ -67,6 +67,9 @@ internal class WalletsUpdateActionResolver @Inject constructor(
selectedWallet = selectedWallet,
)
}
isAnyWalletNameChanged(state, wallets) -> {
getRenameWalletsAction(state, wallets)
}
else -> getUpdateSelectedWalletAction(state, wallets, selectedWallet)
}
}
@ -121,15 +124,35 @@ internal class WalletsUpdateActionResolver @Inject constructor(
return state.getPrevSelectedWallet().id != selectedWallet.walletId
}
private fun isAnyWalletNameChanged(state: WalletScreenState, wallets: List<UserWallet>): Boolean {
val prevWallets = state.wallets.map { it.walletCardState.id to it.walletCardState.title }
val newWallets = wallets.map { it.walletId to it.name }
val prevWalletsIds = prevWallets.map { it.first }
val newWalletsIds = newWallets.map { it.first }
val isAnyNameChanged = (newWallets - prevWallets.toSet()).isNotEmpty()
return prevWalletsIds != newWalletsIds && isAnyNameChanged
}
private fun getRenameWalletsAction(state: WalletScreenState, wallets: List<UserWallet>): Action.RenameWallets {
val prevWallets = state.wallets.map { it.walletCardState.id to it.walletCardState.title }
val newWallets = wallets.map { it.walletId to it.name }
val renamedWallets = newWallets - prevWallets.toSet()
return Action.RenameWallets(
renamedWallets = wallets.filter { wallet -> renamedWallets.any { it.first == wallet.walletId } },
)
}
private fun getUpdateSelectedWalletAction(
state: WalletScreenState,
wallets: List<UserWallet>,
selectedWallet: UserWallet,
): Action {
return when {
isSelectedWalletNameChanged(state, selectedWallet) -> {
Action.UpdateWalletName(selectedWalletId = selectedWallet.walletId, name = selectedWallet.name)
}
isSelectedWalletUnlocked(state, selectedWallet) -> {
Action.UnlockWallet(
selectedWallet = selectedWallet,
@ -143,10 +166,6 @@ internal class WalletsUpdateActionResolver @Inject constructor(
}
}
private fun isSelectedWalletNameChanged(state: WalletScreenState, selectedWallet: UserWallet): Boolean {
return state.getPrevSelectedWallet().title != selectedWallet.name
}
private fun isSelectedWalletUnlocked(state: WalletScreenState, selectedWallet: UserWallet): Boolean {
return state.isSelectedWalletLocked() && !selectedWallet.isLocked
}
@ -215,10 +234,19 @@ internal class WalletsUpdateActionResolver @Inject constructor(
}
}
data class UpdateWalletName(val selectedWalletId: UserWalletId, val name: String) : Action() {
/**
* Rename wallets
*
* @property renamedWallets renamed wallets
*/
data class RenameWallets(val renamedWallets: List<UserWallet>) : Action() {
override fun toString(): String {
return "UpdateWalletName(selectedWalletId = $selectedWalletId, name = $name)"
return """
RenameWallets(
renamedWallets = ${renamedWallets.joinToString { it.walletId.toString() }}
)
""".trimIndent()
}
}

View file

@ -89,11 +89,11 @@ markdownComposeView = "0.5.4"
# endregion Other libraries
# region Tangem
tangemBlockchainSdk = "release-app_5.20-916"
tangemBlockchainSdk = "release-app_5.20-930"
#tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds
tangemCardSdk = "release-app_5.20-423"
tangemCardSdk = "release-app_5.20-431"
#tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^
tangemVico = "2.0.0-alpha.25-tangem17"
tangemVico = "2.0.0-alpha.25-tangem-developments8"
#tangemVico = "0.0.1" # Keep it! - used for local builds ^
# endregion Tangem

View file

@ -7,17 +7,7 @@ import com.tangem.datasource.api.markets.models.response.TokenMarketInfoResponse
import com.tangem.datasource.api.tangemTech.models.CoinsResponse
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
val l2BlockchainsList = listOf(
Blockchain.Optimism,
Blockchain.Arbitrum,
Blockchain.ZkSyncEra,
Blockchain.Manta,
Blockchain.PolygonZkEVM,
Blockchain.Aurora,
Blockchain.Base,
Blockchain.Blast,
Blockchain.Cyber,
)
val l2BlockchainsList = Blockchain.entries.filter { it.isL2EthereumNetwork() }
val l2BlockchainsCoinIds = l2BlockchainsList.map { it.toCoinId() }

View file

@ -143,7 +143,7 @@ object BlockchainUtils {
}
private fun getNetworkNameWithoutTestnet(blockchain: Blockchain): String {
return blockchain.getNetworkName().replace(oldValue = " Testnet", newValue = "")
return blockchain.fullName.replace(oldValue = " Testnet", newValue = "")
}
fun isTokenBetaFunctionality(blockchainId: String): Boolean {

View file

@ -47,7 +47,7 @@ dependencyResolutionManagement {
}
maven {
// setting any repository from tangem project allows maven search all packages in the project
url = uri("https://maven.pkg.github.com/tangem/tangem-sdk-android")
url = uri("https://maven.pkg.github.com/tangem-developments/tangem-sdk-android")
credentials {
username = properties.getProperty("gpr.user") ?: System.getenv("GITHUB_ACTOR")
password = properties.getProperty("gpr.key") ?: System.getenv("GITHUB_TOKEN")
@ -56,7 +56,7 @@ dependencyResolutionManagement {
}
maven {
// setting any repository from tangem project allows maven search all packages in the project
url = uri("https://maven.pkg.github.com/tangem/blst-android")
url = uri("https://maven.pkg.github.com/tangem-developments/blst-android")
credentials {
username = properties.getProperty("gpr.user") ?: System.getenv("GITHUB_ACTOR")
password = properties.getProperty("gpr.key") ?: System.getenv("GITHUB_TOKEN")
@ -65,7 +65,7 @@ dependencyResolutionManagement {
}
maven {
// setting any repository from tangem project allows maven search all packages in the project
url = uri("https://maven.pkg.github.com/tangem/blockchain-sdk-kotlin")
url = uri("https://maven.pkg.github.com/tangem-developments/blockchain-sdk-kotlin")
credentials {
username = properties.getProperty("gpr.user") ?: System.getenv("GITHUB_ACTOR")
password = properties.getProperty("gpr.key") ?: System.getenv("GITHUB_TOKEN")
@ -74,7 +74,7 @@ dependencyResolutionManagement {
}
maven {
// setting any repository from tangem project allows maven search all packages in the project
url = uri("https://maven.pkg.github.com/tangem/wallet-core")
url = uri("https://maven.pkg.github.com/tangem-developments/wallet-core")
credentials {
username = properties.getProperty("gpr.user") ?: System.getenv("GITHUB_ACTOR")
password = properties.getProperty("gpr.key") ?: System.getenv("GITHUB_TOKEN")
@ -86,7 +86,7 @@ dependencyResolutionManagement {
}
maven {
// setting any repository from tangem project allows maven search all packages in the project
url = uri("https://maven.pkg.github.com/tangem/vico")
url = uri("https://maven.pkg.github.com/tangem-developments/vico")
credentials {
username = properties.getProperty("gpr.user") ?: System.getenv("GITHUB_ACTOR")
password = properties.getProperty("gpr.key") ?: System.getenv("GITHUB_TOKEN")
@ -97,7 +97,7 @@ dependencyResolutionManagement {
}
maven {
// setting any repository from tangem project allows maven search all packages in the project
url = uri("https://maven.pkg.github.com/tangem/ic4j-agent")
url = uri("https://maven.pkg.github.com/tangem-developments/ic4j-agent")
credentials {
username = properties.getProperty("gpr.user") ?: System.getenv("GITHUB_ACTOR")
password = properties.getProperty("gpr.key") ?: System.getenv("GITHUB_TOKEN")