Updated on 2026-08-14
This commit is contained in:
parent
e7fe22d1e4
commit
7e60798849
15 changed files with 212 additions and 19 deletions
|
|
@ -65,6 +65,8 @@ dependencies {
|
|||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.10'
|
||||
|
||||
implementation 'com.tangem:blockchain:1.49.0'
|
||||
implementation 'com.tangem:core:1.57.0'
|
||||
implementation 'com.tangem:sdk:1.57.0'
|
||||
|
||||
//lifecycle
|
||||
implementation "androidx.lifecycle:lifecycle-runtime:2.2.0"
|
||||
|
|
|
|||
|
|
@ -34,11 +34,11 @@ class TangemSdkManager(val activity: ComponentActivity) {
|
|||
}
|
||||
|
||||
suspend fun setPasscode(cardId: String?): CompletionResult<SetPinResponse> {
|
||||
return runTaskAsyncReturnOnMain(SetPinCommand.setPin1(null), cardId)
|
||||
return runTaskAsyncReturnOnMain(SetPinCommand.setPin2(null), cardId)
|
||||
}
|
||||
|
||||
suspend fun setAccessCode(cardId: String?): CompletionResult<SetPinResponse> {
|
||||
return runTaskAsyncReturnOnMain(SetPinCommand.setPin2(null), cardId)
|
||||
return runTaskAsyncReturnOnMain(SetPinCommand.setPin1(null), cardId)
|
||||
}
|
||||
|
||||
suspend fun setLongTap(cardId: String?): CompletionResult<SetPinResponse> {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
package com.tangem.tap.domain
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
import com.tangem.TangemError
|
||||
import com.tangem.wallet.R
|
||||
import java.math.BigDecimal
|
||||
|
||||
interface TapErrors
|
||||
interface MultiMessageError : TapErrors {
|
||||
|
|
@ -34,6 +34,14 @@ sealed class TapError(@StringRes val localizedMessage: Int) : Throwable(), TapEr
|
|||
) : TapError(-1), MultiMessageError
|
||||
}
|
||||
|
||||
sealed class TapSdkError(override val messageResId: Int?) : Throwable(), TangemError {
|
||||
final override val code: Int = 1
|
||||
override var customMessage: String = code.toString()
|
||||
|
||||
object CardForDifferentApp : TapSdkError(R.string.error_card_for_different_app)
|
||||
}
|
||||
|
||||
|
||||
fun TapErrors.assembleErrorIds(): MutableList<Int> {
|
||||
val idList = mutableListOf<Int>()
|
||||
when (this) {
|
||||
|
|
|
|||
|
|
@ -79,7 +79,9 @@ class TapWalletManager {
|
|||
|
||||
suspend fun onCardScanned(data: ScanNoteResponse) {
|
||||
withContext(Dispatchers.Main) {
|
||||
store.dispatch(WalletAction.ResetState)
|
||||
store.dispatch(GlobalAction.SaveScanNoteResponse(data))
|
||||
store.dispatch(WalletAction.CheckIfWarningNeeded)
|
||||
val artworkId = data.verifyResponse?.artworkInfo?.id
|
||||
if (data.walletManager != null) {
|
||||
if (!NetworkConnectivity.getInstance().isOnlineOrConnecting()) {
|
||||
|
|
|
|||
|
|
@ -2,14 +2,18 @@ package com.tangem.tap.domain.tasks
|
|||
|
||||
import com.tangem.CardSession
|
||||
import com.tangem.CardSessionRunnable
|
||||
import com.tangem.TangemError
|
||||
import com.tangem.TangemSdkError
|
||||
import com.tangem.blockchain.common.WalletManager
|
||||
import com.tangem.blockchain.common.WalletManagerFactory
|
||||
import com.tangem.commands.Card
|
||||
import com.tangem.commands.CardStatus
|
||||
import com.tangem.commands.CommandResponse
|
||||
import com.tangem.commands.Product
|
||||
import com.tangem.commands.verifycard.VerifyCardCommand
|
||||
import com.tangem.commands.verifycard.VerifyCardResponse
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.tap.domain.TapSdkError
|
||||
import com.tangem.tasks.ScanTask
|
||||
|
||||
data class ScanNoteResponse(
|
||||
|
|
@ -29,6 +33,12 @@ class ScanNoteTask(val card: Card? = null) : CardSessionRunnable<ScanNoteRespons
|
|||
is CompletionResult.Success -> {
|
||||
val card = this.card ?: result.data
|
||||
|
||||
val error = getErrorIfExcludedCard(card)
|
||||
if (error != null) {
|
||||
callback(CompletionResult.Failure(error))
|
||||
return@run
|
||||
}
|
||||
|
||||
val walletManager = try {
|
||||
WalletManagerFactory.makeWalletManager(card)
|
||||
} catch (exception: Exception) {
|
||||
|
|
@ -50,4 +60,21 @@ class ScanNoteTask(val card: Card? = null) : CardSessionRunnable<ScanNoteRespons
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getErrorIfExcludedCard(card: Card): TangemError? {
|
||||
if (card.cardData?.productMask?.contains(Product.Note) != true) {
|
||||
return TapSdkError.CardForDifferentApp
|
||||
}
|
||||
if (excludedBatches.contains(card.cardData?.batchId)) {
|
||||
return TapSdkError.CardForDifferentApp
|
||||
}
|
||||
if (card.status == CardStatus.Purged) return TangemSdkError.CardIsPurged()
|
||||
if (card.status == CardStatus.NotPersonalized) return TangemSdkError.NotPersonalized()
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val excludedBatches = listOf("0027", "0030", "0031")
|
||||
}
|
||||
}
|
||||
|
|
@ -125,7 +125,7 @@ private fun handleSecurityAction(
|
|||
allowedSecurityOptions.add(SecurityOption.AccessCode)
|
||||
}
|
||||
if (allowSetPin2 && (isDefaultPin1 || !prohibitDefaultPin)) {
|
||||
allowedSecurityOptions.add(SecurityOption.AccessCode)
|
||||
allowedSecurityOptions.add(SecurityOption.PassCode)
|
||||
}
|
||||
|
||||
state.copy(securityScreenState = state.securityScreenState?.copy(
|
||||
|
|
|
|||
|
|
@ -14,8 +14,10 @@ import java.math.BigDecimal
|
|||
|
||||
sealed class WalletAction : Action {
|
||||
|
||||
object ResetState : WalletAction()
|
||||
|
||||
object LoadData : WalletAction() {
|
||||
data class Failure(val error: TapError): WalletAction()
|
||||
data class Failure(val error: TapError) : WalletAction()
|
||||
}
|
||||
|
||||
object LoadWallet : WalletAction() {
|
||||
|
|
@ -24,6 +26,13 @@ sealed class WalletAction : Action {
|
|||
data class Failure(val errorMessage: String? = null) : WalletAction()
|
||||
}
|
||||
|
||||
object CheckIfWarningNeeded : WalletAction()
|
||||
object CheckHashesCountOnline : WalletAction()
|
||||
object NeedToCheckHashesCountOnline : WalletAction()
|
||||
object ConfirmHashesCount : WalletAction()
|
||||
data class ShowWarning(val warningType: WarningType) : WalletAction()
|
||||
object SaveCardId : WalletAction()
|
||||
|
||||
object UpdateWallet : WalletAction() {
|
||||
data class Success(val wallet: Wallet) : WalletAction()
|
||||
data class Failure(val errorMessage: String? = null) : WalletAction()
|
||||
|
|
@ -50,6 +59,7 @@ sealed class WalletAction : Action {
|
|||
data class ChooseCurrency(val amounts: List<Amount>?) : WalletAction()
|
||||
object Cancel : WalletAction()
|
||||
}
|
||||
|
||||
object CreatePayId : WalletAction() {
|
||||
data class CompleteCreatingPayId(val payId: String) : WalletAction()
|
||||
data class Success(val payId: String) : WalletAction()
|
||||
|
|
@ -68,7 +78,7 @@ sealed class WalletAction : Action {
|
|||
}
|
||||
|
||||
object ShowQrCode : WalletAction()
|
||||
object HideQrCode : WalletAction()
|
||||
object HideDialog : WalletAction()
|
||||
data class ExploreAddress(val context: Context) : WalletAction()
|
||||
object CreateWallet : WalletAction()
|
||||
object EmptyWallet : WalletAction()
|
||||
|
|
|
|||
|
|
@ -5,7 +5,10 @@ import android.net.Uri
|
|||
import androidx.core.content.ContextCompat
|
||||
import com.tangem.blockchain.common.Amount
|
||||
import com.tangem.blockchain.common.AmountType
|
||||
import com.tangem.blockchain.common.SignatureCountValidator
|
||||
import com.tangem.blockchain.common.Wallet
|
||||
import com.tangem.blockchain.extensions.SimpleResult
|
||||
import com.tangem.commands.Card
|
||||
import com.tangem.commands.common.network.Result
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.common.extensions.toHexString
|
||||
|
|
@ -17,7 +20,9 @@ import com.tangem.tap.domain.PayIdManager
|
|||
import com.tangem.tap.domain.TapError
|
||||
import com.tangem.tap.domain.extensions.toSendableAmounts
|
||||
import com.tangem.tap.features.send.redux.PrepareSendScreen
|
||||
import com.tangem.tap.network.NetworkConnectivity
|
||||
import com.tangem.tap.network.NetworkStateChanged
|
||||
import com.tangem.tap.preferencesStorage
|
||||
import com.tangem.tap.scope
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.tap.tangemSdkManager
|
||||
|
|
@ -65,7 +70,10 @@ val walletMiddleware: Middleware<AppState> = { dispatch, state ->
|
|||
scope.launch { store.state.globalState.tapWalletManager.updateWallet() }
|
||||
}
|
||||
is WalletAction.UpdateWallet.Success -> setupWalletUpdate(action.wallet)
|
||||
is WalletAction.LoadWallet.Success -> setupWalletUpdate(action.wallet)
|
||||
is WalletAction.LoadWallet.Success -> {
|
||||
store.dispatch(WalletAction.CheckHashesCountOnline)
|
||||
setupWalletUpdate(action.wallet)
|
||||
}
|
||||
is WalletAction.CreatePayId.CompleteCreatingPayId -> {
|
||||
scope.launch {
|
||||
val cardId = store.state.globalState.scanNoteResponse?.card?.cardId
|
||||
|
|
@ -100,13 +108,21 @@ val walletMiddleware: Middleware<AppState> = { dispatch, state ->
|
|||
}
|
||||
}
|
||||
}
|
||||
is WalletAction.LoadData, is NetworkStateChanged -> {
|
||||
is WalletAction.LoadData -> {
|
||||
scope.launch {
|
||||
store.state.globalState.scanNoteResponse?.let {
|
||||
store.state.globalState.tapWalletManager.onCardScanned(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
is NetworkStateChanged -> {
|
||||
store.state.globalState.scanNoteResponse?.let { scanNoteResponse ->
|
||||
store.dispatch(WalletAction.CheckHashesCountOnline)
|
||||
scope.launch {
|
||||
store.state.globalState.tapWalletManager.onCardScanned(scanNoteResponse)
|
||||
}
|
||||
}
|
||||
}
|
||||
is WalletAction.CopyAddress -> {
|
||||
store.state.walletState.addressData?.address?.let {
|
||||
action.context.copyToClipboard(it)
|
||||
|
|
@ -125,6 +141,20 @@ val walletMiddleware: Middleware<AppState> = { dispatch, state ->
|
|||
store.dispatch(NavigationAction.NavigateTo(AppScreen.Send))
|
||||
}
|
||||
}
|
||||
is WalletAction.CheckIfWarningNeeded -> {
|
||||
val card = store.state.globalState.scanNoteResponse?.card
|
||||
val validator = store.state.globalState.scanNoteResponse?.walletManager
|
||||
as? SignatureCountValidator
|
||||
if (card != null && !preferencesStorage.wasCardScannedBefore(card.cardId)) {
|
||||
val result = checkIfWarningNeeded(card, validator)
|
||||
if (result != null) store.dispatch(WalletAction.ShowWarning(result))
|
||||
}
|
||||
}
|
||||
is WalletAction.CheckHashesCountOnline -> checkHashesCountOnline()
|
||||
is WalletAction.SaveCardId -> {
|
||||
val cardId = store.state.globalState.scanNoteResponse?.card?.cardId
|
||||
cardId?.let { preferencesStorage.saveScannedCardId(it) }
|
||||
}
|
||||
}
|
||||
next(action)
|
||||
}
|
||||
|
|
@ -132,7 +162,7 @@ val walletMiddleware: Middleware<AppState> = { dispatch, state ->
|
|||
}
|
||||
|
||||
private fun setupWalletUpdate(wallet: Wallet) {
|
||||
if (!wallet.recentTransactions.isNullOrEmpty()) {
|
||||
if (!wallet.recentTransactions.isNullOrEmpty() && !store.state.walletState.updatingWallet) {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
delay(10000)
|
||||
withContext(Dispatchers.Main) {
|
||||
|
|
@ -159,4 +189,48 @@ private fun prepareSendAction(amount: Amount?): Action {
|
|||
PrepareSendScreen(amountToSend)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkIfWarningNeeded(
|
||||
card: Card, signatureCountValidator: SignatureCountValidator? = null
|
||||
): WarningType? {
|
||||
|
||||
// if (card.getType() != CardType.Release) {
|
||||
// return WarningType.DevCard
|
||||
// }
|
||||
|
||||
return if (signatureCountValidator == null) {
|
||||
if (card.walletSignedHashes ?: 0 > 0) {
|
||||
WarningType.CardSignedHashesBefore
|
||||
} else {
|
||||
store.dispatch(WalletAction.SaveCardId)
|
||||
null
|
||||
}
|
||||
} else {
|
||||
store.dispatch(WalletAction.NeedToCheckHashesCountOnline)
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkHashesCountOnline() {
|
||||
if (store.state.walletState.hashesCountVerified != false) return
|
||||
|
||||
if (!NetworkConnectivity.getInstance().isOnlineOrConnecting()) return
|
||||
|
||||
val card = store.state.globalState.scanNoteResponse?.card
|
||||
val validator = store.state.globalState.scanNoteResponse?.walletManager
|
||||
as? SignatureCountValidator
|
||||
|
||||
scope.launch {
|
||||
val result = validator?.validateSignatureCount(card?.walletSignedHashes
|
||||
?: 0)
|
||||
withContext(Dispatchers.Main) {
|
||||
when (result) {
|
||||
SimpleResult.Success -> store.dispatch(WalletAction.ConfirmHashesCount)
|
||||
is SimpleResult.Failure -> store.dispatch(
|
||||
WalletAction.ShowWarning(WarningType.CardSignedHashesBefore)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -31,7 +31,8 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
|
|||
var newState = state.walletState
|
||||
|
||||
when (action) {
|
||||
is WalletAction.EmptyWallet -> newState = WalletState(
|
||||
is WalletAction.ResetState -> newState = WalletState()
|
||||
is WalletAction.EmptyWallet -> newState = newState.copy(
|
||||
state = ProgressState.Done,
|
||||
currencyData = BalanceWidgetData(BalanceStatus.EmptyCard),
|
||||
mainButton = WalletMainButton.CreateWalletButton(true)
|
||||
|
|
@ -45,7 +46,7 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
|
|||
} else {
|
||||
AddressData(wallet.address, wallet.shareUrl, wallet.exploreUrl)
|
||||
}
|
||||
newState = WalletState(
|
||||
newState = newState.copy(
|
||||
state = ProgressState.Error,
|
||||
error = ErrorType.NoInternetConnection,
|
||||
addressData = addressData,
|
||||
|
|
@ -56,7 +57,7 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
|
|||
)
|
||||
}
|
||||
is TapError.UnknownBlockchain -> {
|
||||
newState = WalletState(
|
||||
newState = newState.copy(
|
||||
state = ProgressState.Done,
|
||||
currencyData = BalanceWidgetData(BalanceStatus.UnknownBlockchain)
|
||||
)
|
||||
|
|
@ -77,7 +78,7 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
|
|||
} else {
|
||||
null
|
||||
}
|
||||
newState = WalletState(
|
||||
newState = newState.copy(
|
||||
state = ProgressState.Loading,
|
||||
cardImage = cardImage,
|
||||
currencyData = BalanceWidgetData(
|
||||
|
|
@ -109,7 +110,9 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
|
|||
errorMessage = action.errorMessage
|
||||
)
|
||||
)
|
||||
is WalletAction.UpdateWallet -> newState = newState.copy(updatingWallet = true)
|
||||
is WalletAction.UpdateWallet.Success -> newState = onWalletLoaded(action.wallet, newState)
|
||||
is WalletAction.UpdateWallet.Failure -> newState = newState.copy(updatingWallet = false)
|
||||
is WalletAction.LoadFiatRate -> {
|
||||
newState.copy(currencyData = newState.currencyData.copy(
|
||||
fiatAmount = null,
|
||||
|
|
@ -158,7 +161,7 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
|
|||
)
|
||||
)
|
||||
}
|
||||
is WalletAction.HideQrCode -> {
|
||||
is WalletAction.HideDialog -> {
|
||||
newState = newState.copy(walletDialog = null)
|
||||
}
|
||||
is WalletAction.LoadPayId.Success -> newState = newState.copy(
|
||||
|
|
@ -185,7 +188,12 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
|
|||
)
|
||||
}
|
||||
is WalletAction.Send.Cancel -> newState = newState.copy(walletDialog = null)
|
||||
|
||||
is WalletAction.ShowWarning ->
|
||||
newState = newState.copy(walletDialog = WalletDialog.WarningDialog(action.warningType))
|
||||
is WalletAction.NeedToCheckHashesCountOnline ->
|
||||
newState = newState.copy(hashesCountVerified = false)
|
||||
is WalletAction.ConfirmHashesCount ->
|
||||
newState = newState.copy(hashesCountVerified = true)
|
||||
}
|
||||
return newState
|
||||
}
|
||||
|
|
@ -223,6 +231,7 @@ private fun onWalletLoaded(wallet: Wallet, walletState: WalletState): WalletStat
|
|||
fiatAmount = fiatAmount
|
||||
),
|
||||
pendingTransactions = pendingTransactions,
|
||||
updatingWallet = false,
|
||||
mainButton = WalletMainButton.SendButton(sendButtonEnabled)
|
||||
)
|
||||
}
|
||||
|
|
@ -15,10 +15,12 @@ data class WalletState(
|
|||
val cardImage: Artwork? = null,
|
||||
val wallet: Wallet? = null,
|
||||
val pendingTransactions: List<PendingTransaction> = emptyList(),
|
||||
val hashesCountVerified: Boolean? = null,
|
||||
val addressData: AddressData? = null,
|
||||
val currencyData: BalanceWidgetData = BalanceWidgetData(),
|
||||
val payIdData: PayIdData = PayIdData(),
|
||||
val walletDialog: WalletDialog? = null,
|
||||
val updatingWallet: Boolean = false,
|
||||
val mainButton: WalletMainButton = WalletMainButton.SendButton(false)
|
||||
) : StateType {
|
||||
val showDetails: Boolean =
|
||||
|
|
@ -33,8 +35,11 @@ sealed class WalletDialog {
|
|||
|
||||
data class CreatePayIdDialog(val creatingPayIdState: CreatingPayIdState?) : WalletDialog()
|
||||
data class SelectAmountToSendDialog(val amounts: List<Amount>?) : WalletDialog()
|
||||
data class WarningDialog(val type: WarningType) : WalletDialog()
|
||||
}
|
||||
|
||||
enum class WarningType { CardSignedHashesBefore, DevCard }
|
||||
|
||||
|
||||
enum class ProgressState { Loading, Done, Error }
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import com.tangem.tap.features.wallet.redux.*
|
|||
import com.tangem.tap.features.wallet.ui.dialogs.AmountToSendDialog
|
||||
import com.tangem.tap.features.wallet.ui.dialogs.PayIdDialog
|
||||
import com.tangem.tap.features.wallet.ui.dialogs.QrDialog
|
||||
import com.tangem.tap.features.wallet.ui.dialogs.WarningDialog
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.wallet.R
|
||||
import kotlinx.android.synthetic.main.card_balance.*
|
||||
|
|
@ -229,6 +230,11 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber<Walle
|
|||
this.show(walletDialog.amounts)
|
||||
}
|
||||
}
|
||||
is WalletDialog.WarningDialog -> {
|
||||
if (dialog == null) dialog = WarningDialog(requireContext()).apply {
|
||||
this.show(walletDialog.type)
|
||||
}
|
||||
}
|
||||
null -> {
|
||||
dialog?.dismiss()
|
||||
dialog = null
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ class QrDialog(context: Context) : Dialog(context) {
|
|||
}
|
||||
|
||||
fun showQr(qrCode: Bitmap, shareUrl: String, currencyName: CryptoCurrencyName?) {
|
||||
this.setOnDismissListener { store.dispatch(WalletAction.HideQrCode) }
|
||||
this.btn_done?.setOnClickListener { store.dispatch(WalletAction.HideQrCode) }
|
||||
this.setOnDismissListener { store.dispatch(WalletAction.HideDialog) }
|
||||
this.btn_done?.setOnClickListener { store.dispatch(WalletAction.HideDialog) }
|
||||
|
||||
this.tv_qr_dialog_address?.text = shareUrl
|
||||
this.iv_qrcode?.setImageBitmap(qrCode)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
package com.tangem.tap.features.wallet.ui.dialogs
|
||||
|
||||
import android.content.Context
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import com.tangem.tap.features.wallet.redux.WalletAction
|
||||
import com.tangem.tap.features.wallet.redux.WarningType
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.wallet.R
|
||||
|
||||
class WarningDialog(context: Context) : AlertDialog(context) {
|
||||
|
||||
private val dialog: AlertDialog = Builder(context)
|
||||
.setTitle(context.getString(R.string.generic_warning))
|
||||
.setPositiveButton(context.getString(R.string.general_ok)) { _, _ ->
|
||||
dismiss()
|
||||
}.setOnDismissListener {
|
||||
store.dispatch(WalletAction.SaveCardId)
|
||||
store.dispatch(WalletAction.HideDialog)
|
||||
}
|
||||
.create()
|
||||
|
||||
fun show(warningType: WarningType) {
|
||||
val messageRes = when (warningType) {
|
||||
WarningType.CardSignedHashesBefore -> R.string.warning_card_signed_transactions
|
||||
WarningType.DevCard -> R.string.wallet_warning_dev_card
|
||||
}
|
||||
dialog.setMessage(dialog.context.getString(messageRes))
|
||||
dialog.show()
|
||||
}
|
||||
}
|
||||
|
|
@ -48,15 +48,29 @@ class PreferencesStorage(applicationContext: Application) {
|
|||
fun isFirstLaunch(): Boolean {
|
||||
val isFirst = !preferences.contains(FIRST_LAUNCH_CHECK_KEY)
|
||||
if (isFirst) preferences.edit().putInt(FIRST_LAUNCH_CHECK_KEY, System.currentTimeMillis().toInt()).apply()
|
||||
|
||||
return isFirst
|
||||
}
|
||||
|
||||
fun saveScannedCardId(cardId: String) {
|
||||
val scannedCardsIds: String = restoreScannedCardIds()
|
||||
if (!scannedCardsIds.contains(cardId)) {
|
||||
preferences.edit().putString(SCANNED_CARDS_IDS_KEY, "$scannedCardsIds$cardId, ").apply()
|
||||
}
|
||||
}
|
||||
|
||||
fun wasCardScannedBefore(cardId: String): Boolean {
|
||||
return restoreScannedCardIds().contains(cardId)
|
||||
}
|
||||
|
||||
private fun restoreScannedCardIds(): String =
|
||||
preferences.getString(SCANNED_CARDS_IDS_KEY, "") ?: ""
|
||||
|
||||
companion object {
|
||||
private const val PREFERENCES_NAME = "tapPrefs"
|
||||
private const val APP_CURRENCY_KEY = "appCurrency"
|
||||
private const val FIAT_CURRENCIES_KEY = "fiatCurrencies"
|
||||
private const val FIRST_LAUNCH_CHECK_KEY = "firstLaunchCheck"
|
||||
private const val SCANNED_CARDS_IDS_KEY = "scannedCardIds"
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@
|
|||
<string name="generic_cancel">Cancel</string>
|
||||
<string name="generic_retry">Retry</string>
|
||||
<string name="generic_and">and</string>
|
||||
<string name="generic_warning">Warning</string>
|
||||
|
||||
<string name="notification_address_copied">Address was successfully copied</string>
|
||||
<string name="notification_no_internet">No internet connection</string>
|
||||
|
|
@ -13,7 +14,7 @@
|
|||
|
||||
<string name="home_do_you_have_card">Welcome to Tangem.\nDo you have one of our cards?</string>
|
||||
<string name="home_welcome_back">Welcome back to Tangem Tap. \nScan your card to start.</string>
|
||||
<string name="home_button_yes">Yes!</string>
|
||||
<string name="home_button_yes">Yes. Scan it!</string>
|
||||
<string name="home_button_scan">Scan card</string>
|
||||
<string name="home_button_shop">Shop</string>
|
||||
<string name="home_button_no_card">No</string>
|
||||
|
|
@ -47,10 +48,15 @@
|
|||
<string name="wallet_dialog_pay_id_description">Your PayID is information unique to you, like your phone number, email or ABN.</string>
|
||||
<string name="wallet_dialog_qr_code_header">%s wallet</string>
|
||||
|
||||
<string name="wallet_warning_dev_card">The card you scanned is a development card. Don\'t accept it as a payment.</string>
|
||||
<string name="warning_card_signed_transactions">Warning: This card has been already topped up and signed transactions in the past.
|
||||
Consider immediate withdrawal of all funds if you have received this card from an untrusted source.</string>
|
||||
|
||||
<string name="error_payid_already_created">This PayID already exists. Try a different one.</string>
|
||||
<string name="error_creating_payid">Error response while creating PayID.</string>
|
||||
|
||||
<string name="error_card_for_different_app">This card it is not designed to work with Tangem Tap</string>
|
||||
|
||||
<string name="error_unknown">Unknown error</string>
|
||||
<string name="error_payid_verification_failed">PayID verification failed</string>
|
||||
<string name="error_payid_unsupported_by_blockchain">PayID unsupported by blockchain</string>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue