Updated on 2026-08-14

This commit is contained in:
Tangem 2023-03-02 10:08:09 +03:00
commit 00e4779a40
12 changed files with 96 additions and 68 deletions

View file

@ -11,6 +11,7 @@ import com.tangem.common.doOnFailure
import com.tangem.common.doOnSuccess
import com.tangem.common.services.Result
import com.tangem.core.analytics.Analytics
import com.tangem.datasource.config.ConfigManager
import com.tangem.domain.common.CardDTO
import com.tangem.domain.common.ScanResponse
import com.tangem.domain.common.TapWorkarounds.isTestCard
@ -21,7 +22,6 @@ import com.tangem.tap.common.extensions.dispatchOnMain
import com.tangem.tap.common.extensions.safeUpdate
import com.tangem.tap.common.extensions.setContext
import com.tangem.tap.common.redux.global.GlobalAction
import com.tangem.datasource.config.ConfigManager
import com.tangem.tap.domain.extensions.makePrimaryWalletManager
import com.tangem.tap.domain.extensions.makeWalletManagersForApp
import com.tangem.tap.domain.model.UserWallet
@ -29,6 +29,8 @@ import com.tangem.tap.domain.tokens.models.BlockchainNetwork
import com.tangem.tap.domain.walletStores.WalletStoresError
import com.tangem.tap.features.demo.isDemoCard
import com.tangem.tap.features.details.redux.walletconnect.WalletConnectAction
import com.tangem.tap.features.disclaimer.createDisclaimer
import com.tangem.tap.features.disclaimer.redux.DisclaimerAction
import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsAction
import com.tangem.tap.features.wallet.models.toBlockchainNetworks
import com.tangem.tap.features.wallet.redux.WalletAction
@ -110,8 +112,8 @@ class TapWalletManager {
tangemSdkManager.changeDisplayedCardIdNumbersCount(scanResponse)
store.state.globalState.feedbackManager?.infoHolder?.setCardInfo(scanResponse)
updateConfigManager(scanResponse)
withMainContext {
store.dispatch(DisclaimerAction.SetDisclaimer(card.createDisclaimer()))
store.dispatch(WalletAction.UserWalletChanged(userWallet))
store.dispatch(TwinCardsAction.IfTwinsPrepareState(scanResponse))
store.dispatch(WalletConnectAction.ResetState)

View file

@ -20,7 +20,6 @@ import com.tangem.tap.common.extensions.setContext
import com.tangem.tap.common.redux.global.GlobalAction
import com.tangem.tap.common.redux.navigation.AppScreen
import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.features.disclaimer.DisclaimerType
import com.tangem.tap.features.disclaimer.createDisclaimer
import com.tangem.tap.features.disclaimer.redux.DisclaimerAction
import com.tangem.tap.features.disclaimer.redux.DisclaimerCallback
@ -150,7 +149,7 @@ object ScanCardProcessor {
crossinline nextHandler: suspend (ScanResponse) -> Unit,
crossinline onFailure: suspend (error: TangemError) -> Unit,
) {
val disclaimer = DisclaimerType.get(scanResponse.card).createDisclaimer(scanResponse.card)
val disclaimer = scanResponse.card.createDisclaimer()
store.dispatchOnMain(DisclaimerAction.SetDisclaimer(disclaimer))
if (disclaimer.isAccepted()) {

View file

@ -1,6 +1,5 @@
package com.tangem.tap.domain.walletCurrencies.implementation
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.DerivationStyle
import com.tangem.common.CompletionResult
import com.tangem.common.flatMap
@ -69,7 +68,7 @@ internal class DefaultWalletCurrenciesManager(
.flatMap {
updateWalletStoresAmounts(
userWallet = userWallet,
updatedBlockchains = currenciesToAdd.map { it.blockchain }.distinct(),
updatedCurrencies = currenciesToAddWithMissingBlockchains,
)
}
}
@ -220,11 +219,13 @@ internal class DefaultWalletCurrenciesManager(
private suspend fun updateWalletStoresAmounts(
userWallet: UserWallet,
updatedBlockchains: List<Blockchain>,
updatedCurrencies: List<Currency>,
): CompletionResult<Unit> {
val updatedBlockchains = updatedCurrencies
.filterIsInstance<Currency.Blockchain>()
val updatedWalletStores = walletStoresRepository.get(userWallet.walletId)
.firstOrNull()
?.filter { it.blockchain in updatedBlockchains }
?.filter { it.blockchainWalletData.currency in updatedBlockchains }
?: return CompletionResult.Success(Unit)
return walletAmountsRepository.updateAmountsForWalletStores(

View file

@ -142,8 +142,8 @@ internal class DefaultWalletAmountsRepository(
Timber.e(
error,
"""
Unable to fetch fiat rates
|- Coins ids: $coinsIds
Unable to fetch fiat rates
|- Coins ids: $coinsIds
""".trimIndent(),
)
@ -278,6 +278,7 @@ internal class DefaultWalletAmountsRepository(
Unable to fetch amounts
|- User wallet id: ${walletStore.userWalletId}
|- Blockchain: ${walletStore.blockchain}
|- Derivation path: ${walletStore.derivationPath?.rawPath}
""".trimIndent(),
)
@ -310,6 +311,7 @@ internal class DefaultWalletAmountsRepository(
Fetched amounts
|- User wallet id: ${walletStore.userWalletId}
|- Blockchain: ${walletStore.blockchain}
|- Derivation path: ${walletStore.derivationPath?.rawPath}
""".trimIndent(),
)
@ -337,6 +339,7 @@ internal class DefaultWalletAmountsRepository(
Missed derivation
|- User wallet id: ${walletStore.userWalletId}
|- Blockchain: ${walletStore.blockchain}
|- Derivation path: ${walletStore.derivationPath?.rawPath}
""".trimIndent(),
)
@ -360,6 +363,7 @@ internal class DefaultWalletAmountsRepository(
Wallet manager is null
|- User wallet id: ${walletStore.userWalletId}
|- Blockchain: ${walletStore.blockchain}
|- Derivation path: ${walletStore.derivationPath?.rawPath}
""".trimIndent(),
)
@ -405,6 +409,7 @@ internal class DefaultWalletAmountsRepository(
Fetched wallet rent
|- User wallet id: ${walletStore.userWalletId}
|- Blockchain: ${walletStore.blockchain}
|- Derivation path: ${walletStore.derivationPath?.rawPath}
|- Rent: $rent
""".trimIndent(),
)

View file

@ -51,6 +51,7 @@ internal class DefaultWalletManagersRepository(
val foundWalletManager = findWalletManager(
userWalletId = userWallet.walletId,
blockchain = blockchainNetwork?.blockchain,
derivationPath = blockchainNetwork?.derivationPath,
)
foundWalletManager?.updateTokens(
@ -85,7 +86,13 @@ internal class DefaultWalletManagersRepository(
return when {
blockchain == Blockchain.Unknown || blockchain == null -> {
val error = WalletStoresError.UnknownBlockchain()
Timber.e(error)
Timber.e(
error,
"""
Unknown blockchain while creating wallet manager
|- User wallet ID: ${userWallet.walletId}
""".trimIndent(),
)
CompletionResult.Failure(error)
}
walletManager != null -> {
@ -97,7 +104,15 @@ internal class DefaultWalletManagersRepository(
}
else -> {
val error = WalletStoresError.WalletManagerNotCreated(blockchain)
Timber.e(error)
Timber.e(
error,
"""
Unable to create wallet manager
|- User wallet ID: ${userWallet.walletId}
|- Blockchain: $blockchain
|- Derivation path: ${blockchainNetwork?.derivationPath}
""".trimIndent(),
)
CompletionResult.Failure(error)
}
}
@ -178,15 +193,19 @@ internal class DefaultWalletManagersRepository(
private suspend fun findWalletManager(
userWalletId: UserWalletId,
blockchain: Blockchain?,
derivationPath: String?,
): WalletManager? {
return walletManagersStorage.getAll()
.firstOrNull()
?.get(userWalletId)
?.let { userWalletManagers ->
if (blockchain == null) {
if (blockchain == null || derivationPath == null) {
userWalletManagers.firstOrNull()
} else {
userWalletManagers.firstOrNull { it.wallet.blockchain == blockchain }
userWalletManagers.firstOrNull {
it.wallet.blockchain == blockchain &&
it.wallet.publicKey.derivationPath?.rawPath == derivationPath
}
}
}
}

View file

@ -121,9 +121,10 @@ private inline fun List<WalletStoreModel>.replaceWalletStores(
if (currentWalletStore != updatedWalletStore) {
Timber.d(
"""
Update wallet store in storage
|- User wallet ID: ${updatedWalletStore.userWalletId}
|- Blockchain: ${updatedWalletStore.blockchain}
Update wallet store in storage
|- User wallet ID: ${updatedWalletStore.userWalletId}
|- Blockchain: ${updatedWalletStore.blockchain}
|- Derivation path: ${updatedWalletStore.derivationPath?.rawPath}
""".trimIndent(),
)

View file

@ -35,6 +35,8 @@ fun DisclaimerType.createDisclaimer(cardDTO: CardDTO): Disclaimer {
}
}
fun CardDTO.createDisclaimer(): Disclaimer = DisclaimerType.get(this).createDisclaimer(this)
private fun provideDisclaimerDataProvider(cardId: String): DisclaimerDataProvider {
return object : DisclaimerDataProvider {
override fun getLanguage(): String = Locale.getDefault().language

View file

@ -77,36 +77,35 @@ data class WalletData(
if (currencyData.status == BalanceStatus.SameCurrencyTransactionInProgress) {
walletWarnings.add(WalletWarning.TransactionInProgress(currency.currencyName))
}
}
private fun assembleBlockchainWarnings(walletWarnings: MutableList<WalletWarning>) {
if (!currency.isBlockchain()) return
if (existentialDepositString != null) {
val warning = WalletWarning.ExistentialDeposit(
currencyName = currency.currencyName,
edStringValueWithSymbol = "$existentialDepositString ${currency.currencySymbol}",
)
walletWarnings.add(warning)
}
if (walletRent != null) {
walletWarnings.add(WalletWarning.Rent(walletRent))
}
}
private fun assembleTokenWarnings(walletWarnings: MutableList<WalletWarning>) {
with(currency) {
if (!isToken()) return
private fun assembleBlockchainWarnings(walletWarnings: MutableList<WalletWarning>) = with(currency) {
if (!isBlockchain()) return
if (blockchainAmountIsEmpty() && !tokenAmountIsEmpty()) {
walletWarnings.add(
WalletWarning.BalanceNotEnoughForFee(
currencyName = currencyName,
blockchainFullName = blockchain.fullName,
blockchainSymbol = blockchain.currency,
),
)
}
if (existentialDepositString != null) {
val warning = WalletWarning.ExistentialDeposit(
currencyName = currencyName,
edStringValueWithSymbol = "$existentialDepositString $currencySymbol",
)
walletWarnings.add(warning)
}
}
private fun assembleTokenWarnings(walletWarnings: MutableList<WalletWarning>) = with(currency) {
if (!isToken()) return
if (blockchainAmountIsEmpty() && !tokenAmountIsEmpty()) {
walletWarnings.add(
WalletWarning.BalanceNotEnoughForFee(
currencyName = currencyName,
blockchainFullName = blockchain.fullName,
blockchainSymbol = blockchain.currency,
),
)
}
}

View file

@ -144,7 +144,9 @@ class UserWalletManagerImpl(
val card = requireNotNull(appStateHolder.getActualCard()) { "card not found" }
val blockchainNetwork = BlockchainNetwork(blockchain, card)
val walletManager = appStateHolder.walletState?.getWalletManager(blockchainNetwork)
return walletManager?.wallet?.recentTransactions?.lastOrNull()?.hash?.let { HEX_PREFIX + it }
return walletManager?.wallet?.recentTransactions
?.lastOrNull { it.hash?.isNotEmpty() == true }
?.hash?.let { HEX_PREFIX + it }
}
override suspend fun getCurrentWalletTokensBalance(

View file

@ -1,17 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="42dp">
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="42dp">
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.5" />
android:id="@+id/guideline_horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.5" />
<TextView
android:id="@+id/tv_currency"
@ -64,16 +64,19 @@
android:id="@+id/tv_status"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:ellipsize="end"
android:maxLines="1"
android:textColor="@color/text_tertiary"
android:textSize="12sp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/tv_amount"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/guideline_horizontal"
app:lineHeight="20dp"
tools:text="Unreachable..." />
tools:text="Transaction in progress and it very long text with some strange status"
tools:visibility="visible" />
<TextView
android:id="@+id/tv_exchange_rate"
@ -86,5 +89,7 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/guideline_horizontal"
app:lineHeight="20dp"
tools:text="46 908 $" />
tools:text="46 908 $"
tools:visibility="gone" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -65,7 +65,7 @@ object Versions {
// const val tangemBlockchainSdk = "0.0.1" // Keep it! - used for local builds
const val tangemCardSdk = "develop-191"
// const val tangemCardSgk = "0.0.1" // Keep it! - used for local builds
// const val tangemCardSdk = "0.0.1" // Keep it! - used for local builds
// endregion Tangem
// region Tools

View file

@ -13,15 +13,12 @@ val FirmwareVersion.Companion.SolanaTokensAvailable
get() = FirmwareVersion(4, 52)
fun CardDTO.supportedBlockchains(): List<Blockchain> {
val supportedBlockchains = when {
firmwareVersion < FirmwareVersion.MultiWalletAvailable -> {
Blockchain.fromCurve(EllipticCurve.Secp256k1)
}
else -> {
(Blockchain.fromCurve(EllipticCurve.Secp256k1) + Blockchain.fromCurve(EllipticCurve.Ed25519)).distinct()
}
val supportedBlockchains = if (firmwareVersion < FirmwareVersion.MultiWalletAvailable) {
Blockchain.fromCurve(EllipticCurve.Secp256k1)
} else {
wallets.flatMap { Blockchain.fromCurve(it.curve) }.distinct()
}
return supportedBlockchains
.filter { isTestCard == it.isTestnet() }
.filter { it.isSupportedInApp() }
@ -38,12 +35,8 @@ fun CardDTO.supportedTokens(): List<Blockchain> {
}
}
}
val filtered = tokensSupportedByCard.filter { isTestCard == it.isTestnet() }
return filtered
}
fun CardDTO.canHandleBlockchain(blockchain: Blockchain): Boolean {
return this.supportedBlockchains().contains(blockchain)
return tokensSupportedByCard.filter { isTestCard == it.isTestnet() }
}
fun CardDTO.canHandleToken(blockchain: Blockchain): Boolean {