Updated on 2026-08-14

This commit is contained in:
Tangem 2022-10-01 20:16:49 +05:00
parent a642b39aa7
commit d9516b5316
9 changed files with 101 additions and 29 deletions

View file

@ -1,5 +1,6 @@
package com.tangem.tap.features.details.ui.details
import com.tangem.domain.common.TapWorkarounds.isSaltPay
import com.tangem.domain.common.TapWorkarounds.isStart2Coin
import com.tangem.tap.common.feedback.FeedbackEmail
import com.tangem.tap.common.feedback.SupportInfo
@ -25,7 +26,9 @@ class DetailsViewModel(private val store: Store<AppState>) {
if (state.scanResponse?.card?.isMultiwalletAllowed == true) it else null
}
SettingsElement.LinkMoreCards -> {
if (state.createBackupAllowed) it else null
// if (state.createBackupAllowed) it else null
// TODO: SaltPay: temporary excluding backup process for Visa cards
if (state.createBackupAllowed && state.scanResponse?.card?.isSaltPay != true) it else null
}
SettingsElement.PrivacyPolicy -> {
if (state.privacyPolicyUrl != null) it else null

View file

@ -1,5 +1,6 @@
package com.tangem.tap.features.home.redux
import com.tangem.domain.common.TapWorkarounds.isSaltPayVisa
import com.tangem.domain.common.extensions.withMainContext
import com.tangem.tap.DELAY_SDK_DIALOG_CLOSE
import com.tangem.tap.common.analytics.AnalyticsEvent
@ -64,7 +65,7 @@ private val homeMiddleware: Middleware<AppState> = { _, _ ->
}
store.state.globalState.analyticsHandlers?.triggerEvent(
event = AnalyticsEvent.GET_CARD,
params = mapOf(AnalyticsParam.SOURCE.param to GetCardSourceParams.WELCOME.param)
params = mapOf(AnalyticsParam.SOURCE.param to GetCardSourceParams.WELCOME.param),
)
}
}
@ -82,6 +83,17 @@ private fun handleReadCard() {
store.state.globalState.tapWalletManager.updateConfigManager(scanResponse)
store.dispatch(TwinCardsAction.IfTwinsPrepareState(scanResponse))
// TODO: SaltPay: temporary excluding backup process for Visa cards
if (scanResponse.card.isSaltPayVisa) {
scope.launch {
store.onCardScanned(scanResponse)
withMainContext {
navigateTo(AppScreen.Wallet, null)
}
}
return@ScanCard
}
if (OnboardingHelper.isOnboardingCase(scanResponse)) {
val navigateTo = OnboardingHelper.whereToNavigate(scanResponse)
store.dispatch(GlobalAction.Onboarding.Start(scanResponse))

View file

@ -9,7 +9,7 @@ import com.tangem.domain.common.TapWorkarounds
import com.tangem.domain.common.TapWorkarounds.isSaltPay
import com.tangem.domain.common.extensions.withMainContext
import com.tangem.operations.backup.BackupService
import com.tangem.tap.*
import com.tangem.tap.backupService
import com.tangem.tap.common.extensions.dispatchOnMain
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.common.redux.global.GlobalAction
@ -21,6 +21,11 @@ import com.tangem.tap.features.demo.DemoHelper
import com.tangem.tap.features.home.redux.HomeAction
import com.tangem.tap.features.wallet.redux.Artwork
import com.tangem.tap.features.wallet.redux.WalletAction
import com.tangem.tap.preferencesStorage
import com.tangem.tap.scope
import com.tangem.tap.store
import com.tangem.tap.tangemSdk
import com.tangem.tap.tangemSdkManager
import kotlinx.coroutines.launch
import org.rekotlin.Action
import org.rekotlin.Middleware
@ -217,7 +222,7 @@ private fun handleBackupAction(appState: () -> AppState?, action: BackupAction)
is BackupAction.AddBackupCard -> {
backupService.skipCompatibilityChecks = true
tangemSdk.config.filter.cardIdFilter =
CardFilter.Companion.ItemFilter.Allow(TapWorkarounds.saltPayCardIds.toSet())
CardFilter.Companion.ItemFilter.Allow(TapWorkarounds.saltPayTangemCardIds.toSet())
backupService.addBackupCard { result ->
backupService.skipCompatibilityChecks = false

View file

@ -438,8 +438,7 @@ private fun setSingleWalletFiatRates(
appCurrency: FiatCurrency,
rateFormatter: (BigDecimal) -> String,
state: WalletState,
):
WalletState {
): WalletState {
val blockchainFiatRate = fiatRates.entries.firstOrNull { it.key.isBlockchain() }
val tokenFiatRate = fiatRates.entries.firstOrNull { it.key.isToken() }
Timber.e("Token Fiat Rate is ${tokenFiatRate ?: "NULL"}")

View file

@ -1,12 +1,15 @@
package com.tangem.tap.features.wallet.ui.wallet
import com.tangem.domain.common.extensions.debounce
import com.tangem.tap.common.entities.FiatCurrency
import com.tangem.tap.common.extensions.animateVisibility
import com.tangem.tap.common.extensions.formatAmountAsSpannedString
import com.tangem.tap.features.wallet.redux.ProgressState
import com.tangem.tap.features.wallet.redux.WalletAction
import com.tangem.tap.mainScope
import com.tangem.tap.store
import com.tangem.wallet.databinding.LayoutSingleWalletBalanceBinding
import org.rekotlin.Action
import java.math.BigDecimal
data class SaltPayBalanceWidgetData(
@ -26,7 +29,7 @@ class SaltPayBalanceWidget(
veilBalance.veil()
veilBalanceCrypto.veil()
} else {
veilBalance.unVeil()
// veilBalance.unVeil()
veilBalanceCrypto.unVeil()
}
tvProcessing.animateVisibility(
@ -35,9 +38,18 @@ class SaltPayBalanceWidget(
veilBalanceCrypto.animateVisibility(
show = data.state != ProgressState.Error,
)
tvBalance.text = data.fiatAmount?.formatAmountAsSpannedString(
currencySymbol = data.fiatCurrency?.symbol ?: "",
)
if (data.fiatAmount == null) {
//TODO: SaltPay: A tricky solution to the problem with displaying rates
// If the rates are loaded after the walletManager.update() is completely updated,
// then this problem can be avoided
actionDebouncer(WalletAction.LoadFiatRate())
} else {
veilBalance.unVeil()
tvBalance.text = data.fiatAmount?.formatAmountAsSpannedString(
currencySymbol = data.fiatCurrency?.symbol ?: "",
)
}
tvBalanceCrypto.text = data.currency
tvCurrencyName.text = data.fiatCurrency?.code
@ -48,4 +60,5 @@ class SaltPayBalanceWidget(
}
}
private val actionDebouncer = debounce<Action>(500, mainScope) { store.dispatch(it) }

View file

@ -1,9 +1,9 @@
ext.versions = [
kotlin : '1.6.10',
build_gradle : '7.1.3',
tangem_card_sdk : 'develop-159',
// tangem_card_sdk: '0.0.1',
tangem_blockchain_sdk: 'develop-115',
// tangem_card_sdk : 'develop-159',
tangem_card_sdk: '0.0.1',
tangem_blockchain_sdk: 'develop-122',
// tangem_blockchain_sdk: '0.0.1',
]

View file

@ -16,8 +16,15 @@ object TapWorkarounds {
val Card.isStart2Coin: Boolean
get() = isStart2CoinIssuer(issuer.name)
val Card.isSaltPay: Boolean
get() = saltPayCardIds.contains(cardId) || saltPayBatches.contains(batchId)
get() = isSaltPayVisa || isSaltPayTangem
val Card.isSaltPayVisa: Boolean
get() = saltPayVisaBatches.contains(batchId)
val Card.isSaltPayTangem: Boolean
get() = saltPayTangemCardIds.contains(cardId)
val Card.isTestCard: Boolean
get() = batchId == TEST_CARD_BATCH && cardId.startsWith(TEST_CARD_ID_STARTS_WITH)
@ -60,7 +67,7 @@ object TapWorkarounds {
)
private val excludedIssuers = listOf(
"TTM BANK"
"TTM BANK",
)
private val tangemWalletBatches = listOf("AC01")
@ -84,11 +91,9 @@ object TapWorkarounds {
"AC01", "AC02", "CB95",
)
val saltPayCardIds = listOf(
"AE02000000000194",
"AC03000000076195",
"AC79000000000012", // TODO: remove my testing CIDs
"AC79000000000004",// TODO: remove my testing CIDs
val saltPayTangemCardIds = listOf(
"AC01000000000015", // TODO: remove testing CIDs
"AC03000000000088", // TODO: remove testing CIDs
"AC03000000076070",
"AC03000000076088",
"AC03000000076096",
@ -105,17 +110,32 @@ object TapWorkarounds {
"AC03000000076203",
"AC03000000076211",
"AC03000000076229",
// TODO: add cids
// added 01.10.2022
"AC01000000033503",
"AC01000000033594",
"AC01000000033586",
"AC01000000034477",
"AC01000000032760",
"AC01000000033867",
"AC01000000032653",
"AC01000000032752",
"AC01000000034485",
"AC01000000033644",
"AC01000000037454",
"AC01000000037462",
)
val saltPayBatches = listOf("AE02")
private val saltPayVisaBatches = listOf(
"AE02",
"AE03",
)
val saltPayToken: Token
get() = Token(
name = "Wrapped xDAI",
"WxDAI",
"0x4346186e7461cB4DF06bCFCB4cD591423022e417",
18,
symbol = "WxDAI",
contractAddress = "0x4346186e7461cB4DF06bCFCB4cD591423022e417",
decimals = 18,
id = "xdai",
)
}

View file

@ -44,6 +44,7 @@ fun Blockchain.Companion.fromNetworkId(networkId: String): Blockchain? {
"optimistic-ethereum" -> Blockchain.Optimism
"optimistic-ethereum/test" -> Blockchain.OptimismTestnet
"dash" -> Blockchain.Dash
"wxdai" -> Blockchain.SaltPay
else -> null
}
}
@ -92,7 +93,7 @@ fun Blockchain.toNetworkId(): String {
Blockchain.Optimism -> "optimistic-ethereum"
Blockchain.OptimismTestnet -> "optimistic-ethereum/test"
Blockchain.Dash -> "dash"
Blockchain.SaltPay -> "xdai"//TODO
Blockchain.SaltPay -> "wxdai"
else -> "unknown" // TODO
}
}
@ -119,11 +120,10 @@ fun Blockchain.toCoinId(): String {
Blockchain.Tezos -> "tezos"
Blockchain.XRP -> "ripple"
Blockchain.Dogecoin -> "dogecoin"
Blockchain.Gnosis -> "xdai"
Blockchain.Gnosis, Blockchain.SaltPay -> "xdai"
Blockchain.Kusama -> "kusama"
Blockchain.Optimism, Blockchain.OptimismTestnet -> "ethereum"
Blockchain.Dash -> "dash"
Blockchain.SaltPay -> "xdai" //TODO
Blockchain.Unknown -> "unknown"
else -> "unknown" // TODO
}

View file

@ -1,7 +1,11 @@
package com.tangem.domain.common.extensions
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
/**
@ -9,4 +13,20 @@ import kotlinx.coroutines.withContext
*/
suspend fun <T> withMainContext(block: suspend CoroutineScope.() -> T): T = withContext(Dispatchers.Main, block)
suspend fun <T> withIOContext(block: suspend CoroutineScope.() -> T): T = withContext(Dispatchers.IO, block)
suspend fun <T> withIOContext(block: suspend CoroutineScope.() -> T): T = withContext(Dispatchers.IO, block)
fun <T> debounce(
waitMs: Long = 300L,
coroutineScope: CoroutineScope,
runDestinationOn: CoroutineDispatcher = Dispatchers.Unconfined,
destinationFunction: (T) -> Unit,
): (T) -> Unit {
var debounceJob: Job? = null
return { param: T ->
debounceJob?.cancel()
debounceJob = coroutineScope.launch {
delay(waitMs)
withContext(runDestinationOn) { destinationFunction(param) }
}
}
}