Updated on 2026-08-14
This commit is contained in:
parent
9e1ceea2dc
commit
07400563cf
7 changed files with 56 additions and 26 deletions
|
|
@ -25,6 +25,10 @@ import timber.log.Timber
|
|||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@Deprecated(
|
||||
message = "Use WalletStoresManager.fetch({userWalletId}, refresh = true) (to update all user wallet tokens)" +
|
||||
"or WalletCurrenciesManager.update(...) (to update only one user wallet blockchain and its tokens) instead",
|
||||
)
|
||||
@Suppress("MagicNumber")
|
||||
suspend fun WalletManager.safeUpdate(): Result<Wallet> = try {
|
||||
val scanResponse = store.state.globalState.scanResponse
|
||||
|
|
|
|||
|
|
@ -72,9 +72,12 @@ class TapWalletManager {
|
|||
.doOnFailure { error ->
|
||||
val errorAction = when (error) {
|
||||
is WalletStoresError -> when (error) {
|
||||
is WalletStoresError.FetchFiatRatesError,
|
||||
is WalletStoresError.UpdateWalletManagerError,
|
||||
-> WalletAction.LoadData.Failure(error = null)
|
||||
is WalletStoresError.FetchFiatRatesError -> WalletAction.LoadData.Failure(error = null)
|
||||
is WalletStoresError.UpdateWalletManagerTokensError -> WalletAction.LoadData.Failure(
|
||||
error = TapError.WalletManager.InternalError(
|
||||
message = error.cause.localizedMessage ?: error.customMessage,
|
||||
),
|
||||
)
|
||||
is WalletStoresError.WalletManagerNotCreated -> WalletAction.LoadData.Failure(
|
||||
error = TapError.WalletManager.CreationError,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -35,10 +35,10 @@ sealed class WalletStoresError(code: Int) : TangemError(code) {
|
|||
}
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
class UpdateWalletManagerError(
|
||||
class UpdateWalletManagerTokensError(
|
||||
blockchain: Blockchain,
|
||||
override val cause: Throwable,
|
||||
) : WalletStoresError(600015) {
|
||||
override var customMessage: String = "Unable to update wallet manager for currency $blockchain: $cause"
|
||||
override var customMessage: String = "Unable to update wallet manager tokens for currency $blockchain: $cause"
|
||||
}
|
||||
}
|
||||
|
|
@ -153,7 +153,7 @@ internal class DefaultWalletStoresManager(
|
|||
.flatMapOnFailure { error ->
|
||||
when (error) {
|
||||
is WalletStoresError.WalletManagerNotCreated,
|
||||
is WalletStoresError.UpdateWalletManagerError,
|
||||
is WalletStoresError.UpdateWalletManagerTokensError,
|
||||
-> storeWalletStore(null)
|
||||
else -> CompletionResult.Failure(error)
|
||||
}
|
||||
|
|
@ -178,7 +178,7 @@ internal class DefaultWalletStoresManager(
|
|||
.flatMapOnFailure { error ->
|
||||
when (error) {
|
||||
is WalletStoresError.WalletManagerNotCreated,
|
||||
is WalletStoresError.UpdateWalletManagerError,
|
||||
is WalletStoresError.UpdateWalletManagerTokensError,
|
||||
-> CompletionResult.Success(Unit)
|
||||
else -> CompletionResult.Failure(error)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@ package com.tangem.tap.domain.walletStores.repository.implementation
|
|||
|
||||
import com.tangem.blockchain.blockchains.solana.RentProvider
|
||||
import com.tangem.blockchain.common.AmountType
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.BlockchainSdkError
|
||||
import com.tangem.blockchain.common.TransactionHistoryProvider
|
||||
import com.tangem.blockchain.common.Wallet
|
||||
import com.tangem.blockchain.common.WalletManager
|
||||
import com.tangem.blockchain.extensions.Result.Failure
|
||||
|
|
@ -17,9 +19,9 @@ import com.tangem.common.map
|
|||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||
import com.tangem.domain.common.ScanResponse
|
||||
import com.tangem.domain.common.util.UserWalletId
|
||||
import com.tangem.tap.common.TestActions
|
||||
import com.tangem.tap.common.entities.FiatCurrency
|
||||
import com.tangem.tap.common.extensions.replaceByOrAdd
|
||||
import com.tangem.tap.common.extensions.safeUpdate
|
||||
import com.tangem.tap.domain.model.UserWallet
|
||||
import com.tangem.tap.domain.model.WalletStoreModel
|
||||
import com.tangem.tap.domain.walletStores.WalletStoresError
|
||||
|
|
@ -37,6 +39,7 @@ import com.tangem.tap.domain.walletStores.repository.implementation.utils.update
|
|||
import com.tangem.tap.domain.walletStores.storage.WalletManagerStorage
|
||||
import com.tangem.tap.domain.walletStores.storage.WalletStoresStorage
|
||||
import com.tangem.tap.features.demo.DemoHelper
|
||||
import com.tangem.tap.features.demo.isDemoCard
|
||||
import com.tangem.tap.features.wallet.models.Currency
|
||||
import com.tangem.tap.features.wallet.models.PendingTransactionType
|
||||
import com.tangem.tap.features.wallet.models.filterByCoin
|
||||
|
|
@ -47,10 +50,12 @@ import kotlinx.coroutines.Dispatchers
|
|||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import kotlinx.coroutines.withContext
|
||||
import timber.log.Timber
|
||||
import java.math.BigDecimal
|
||||
import kotlin.time.Duration
|
||||
|
||||
@Suppress("LargeClass")
|
||||
internal class DefaultWalletAmountsRepository(
|
||||
|
|
@ -118,8 +123,12 @@ internal class DefaultWalletAmountsRepository(
|
|||
walletStores: List<WalletStoreModel>?,
|
||||
fiatCurrency: FiatCurrency,
|
||||
): CompletionResult<Unit> {
|
||||
val walletStoresInternal = walletStores ?: getWalletStores(userWallets)
|
||||
// FIXME: Use NetworkConnectionManager when it is added to DI
|
||||
if (!NetworkConnectivity.getInstance().isOnlineOrConnecting()) {
|
||||
return CompletionResult.Failure(WalletStoresError.NoInternetConnection)
|
||||
}
|
||||
|
||||
val walletStoresInternal = walletStores ?: getWalletStores(userWallets)
|
||||
val currencies = walletStoresInternal
|
||||
.asSequence()
|
||||
.flatMap { it.walletsData }
|
||||
|
|
@ -177,6 +186,14 @@ internal class DefaultWalletAmountsRepository(
|
|||
scanResponse: ScanResponse,
|
||||
walletStores: List<WalletStoreModel>,
|
||||
): CompletionResult<Unit> = coroutineScope {
|
||||
// FIXME: Use NetworkConnectionManager when it is added to DI
|
||||
if (!NetworkConnectivity.getInstance().isOnlineOrConnecting()) {
|
||||
walletStores.forEach {
|
||||
updateWalletStoreWithUnreachable(it)
|
||||
}
|
||||
return@coroutineScope CompletionResult.Failure(WalletStoresError.NoInternetConnection)
|
||||
}
|
||||
|
||||
walletStores.map { walletStore ->
|
||||
async {
|
||||
// TODO: Find wallet manager via [com.tangem.tap.domain.walletStores.repository.WalletManagersRepository]
|
||||
|
|
@ -206,8 +223,8 @@ internal class DefaultWalletAmountsRepository(
|
|||
updateWalletStoreWithUnreachable(walletStore)
|
||||
}
|
||||
else -> {
|
||||
withInternetConnection { walletManager.safeUpdate() }
|
||||
.map { updateWalletManagerWithAmounts(userWalletId, walletManager) }
|
||||
updateWalletManager(scanResponse, walletManager)
|
||||
.map { updateWalletManagerInStorage(userWalletId, walletManager) }
|
||||
.flatMap {
|
||||
updateWalletStoreWithAmounts(
|
||||
walletStore = walletStore,
|
||||
|
|
@ -228,6 +245,24 @@ internal class DefaultWalletAmountsRepository(
|
|||
}
|
||||
}
|
||||
|
||||
private suspend fun updateWalletManager(
|
||||
scanResponse: ScanResponse,
|
||||
walletManager: WalletManager,
|
||||
demoCardsDelay: Duration = with(Duration) { 500.milliseconds },
|
||||
): CompletionResult<Unit> = catching {
|
||||
if (scanResponse.isDemoCard() || TestActions.testAmountInjectionForWalletManagerEnabled) {
|
||||
delay(demoCardsDelay)
|
||||
TestActions.testAmountInjectionForWalletManagerEnabled = false
|
||||
} else {
|
||||
walletManager.update()
|
||||
|
||||
val wallet = walletManager.wallet
|
||||
if (wallet.blockchain == Blockchain.SaltPay && walletManager is TransactionHistoryProvider) {
|
||||
walletManager.getTransactionHistory(wallet.address, wallet.blockchain, wallet.getTokens())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun fetchWalletStoreRentIfNeeded(
|
||||
walletStore: WalletStoreModel,
|
||||
walletManager: WalletManager,
|
||||
|
|
@ -426,19 +461,7 @@ internal class DefaultWalletAmountsRepository(
|
|||
}
|
||||
}
|
||||
|
||||
private suspend inline fun withInternetConnection(crossinline block: suspend () -> Unit): CompletionResult<Unit> {
|
||||
return if (!NetworkConnectivity.getInstance().isOnlineOrConnecting()) {
|
||||
val error = WalletStoresError.NoInternetConnection
|
||||
Timber.e(error)
|
||||
CompletionResult.Failure(error)
|
||||
} else {
|
||||
withContext(Dispatchers.IO) {
|
||||
catching { block() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun updateWalletManagerWithAmounts(
|
||||
private suspend fun updateWalletManagerInStorage(
|
||||
userWalletId: UserWalletId,
|
||||
walletManager: WalletManager,
|
||||
) = withContext(Dispatchers.Default) {
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@ internal class DefaultWalletManagersRepository(
|
|||
walletManager
|
||||
}
|
||||
.mapFailure {
|
||||
val error = WalletStoresError.UpdateWalletManagerError(
|
||||
val error = WalletStoresError.UpdateWalletManagerTokensError(
|
||||
blockchain = walletManager.wallet.blockchain,
|
||||
cause = it,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ class WalletMiddleware {
|
|||
Timber.e("Unable to proceed with changed network state, no user wallet selected")
|
||||
return
|
||||
}
|
||||
scope.launch { globalState.tapWalletManager.loadData(selectedUserWallet) }
|
||||
scope.launch { globalState.tapWalletManager.loadData(selectedUserWallet, refresh = true) }
|
||||
}
|
||||
is WalletAction.CopyAddress -> {
|
||||
Analytics.send(Token.Receive.ButtonCopyAddress())
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue