Updated on 2026-08-14
This commit is contained in:
commit
7e7c274dcc
7 changed files with 94 additions and 63 deletions
|
|
@ -1,7 +1,7 @@
|
|||
package com.tangem.tap.domain
|
||||
|
||||
import com.tangem.blockchain.common.*
|
||||
import com.tangem.blockchain.extensions.getBlockchain
|
||||
import com.tangem.commands.common.card.Card
|
||||
import com.tangem.commands.common.card.CardStatus
|
||||
import com.tangem.commands.common.network.Result
|
||||
import com.tangem.tap.common.analytics.AnalyticsEvent
|
||||
|
|
@ -14,6 +14,7 @@ import com.tangem.tap.domain.configurable.config.ConfigManager
|
|||
import com.tangem.tap.domain.extensions.amountToCreateAccount
|
||||
import com.tangem.tap.domain.extensions.isNoAccountError
|
||||
import com.tangem.tap.domain.tasks.ScanNoteResponse
|
||||
import com.tangem.tap.domain.tokens.CardCurrencies
|
||||
import com.tangem.tap.domain.twins.TwinsHelper
|
||||
import com.tangem.tap.domain.twins.isTwinCard
|
||||
import com.tangem.tap.features.tokens.redux.TokensAction
|
||||
|
|
@ -32,7 +33,7 @@ class TapWalletManager {
|
|||
private val blockchainSdkConfig by lazy {
|
||||
store.state.globalState.configManager?.config?.blockchainSdkConfig ?: BlockchainSdkConfig()
|
||||
}
|
||||
private val walletManagerFactory: WalletManagerFactory
|
||||
val walletManagerFactory: WalletManagerFactory
|
||||
by lazy { WalletManagerFactory(blockchainSdkConfig) }
|
||||
|
||||
suspend fun loadWalletData(walletManager: WalletManager) {
|
||||
|
|
@ -131,36 +132,20 @@ class TapWalletManager {
|
|||
val config = store.state.globalState.configManager?.config ?: return@withContext
|
||||
|
||||
val primaryWalletManager = data.walletManager
|
||||
val primaryBlockchain = listOf(data.walletManager.wallet.blockchain)
|
||||
val primaryBlockchain = data.walletManager.wallet.blockchain
|
||||
val primaryTokenSymbol = data.card.cardData?.tokenSymbol
|
||||
val primaryToken = primaryWalletManager.presetTokens.toList()
|
||||
.firstOrNull { it.symbol == primaryTokenSymbol }
|
||||
|
||||
store.dispatch(WalletAction.MultiWallet.SetPrimaryBlockchain(primaryBlockchain[0]))
|
||||
store.dispatch(WalletAction.MultiWallet.SetPrimaryBlockchain(primaryBlockchain))
|
||||
if (primaryToken != null) {
|
||||
store.dispatch(WalletAction.MultiWallet.SetPrimaryToken(primaryToken))
|
||||
}
|
||||
|
||||
if (data.card.isMultiwalletAllowed) {
|
||||
val savedCurrencies = currenciesRepository.loadCardCurrencies(data.card.cardId)
|
||||
|
||||
val walletManagers = listOf(primaryWalletManager) +
|
||||
currenciesRepository.getBlockchains()
|
||||
.filterNot { it == primaryWalletManager.wallet.blockchain }
|
||||
.mapNotNull { walletManagerFactory.makeWalletManager(data.card, it) }
|
||||
val otherBlockhains = savedCurrencies.blockchains
|
||||
|
||||
val presetTokens = walletManagers.first { it.wallet.blockchain == data.card.getBlockchain() }
|
||||
.presetTokens.toList()
|
||||
val tokens = presetTokens + savedCurrencies.tokens
|
||||
|
||||
store.dispatch(WalletAction.MultiWallet.AddWalletManagers(walletManagers))
|
||||
store.dispatch(WalletAction.MultiWallet.AddBlockchains(primaryBlockchain + otherBlockhains))
|
||||
store.dispatch(WalletAction.MultiWallet.AddTokens(tokens))
|
||||
store.dispatch(WalletAction.MultiWallet.FindTokensInUse)
|
||||
loadMultiWalletData(data.card, primaryBlockchain, primaryWalletManager)
|
||||
} else {
|
||||
store.dispatch(WalletAction.MultiWallet.AddWalletManagers(listOf(primaryWalletManager)))
|
||||
store.dispatch(WalletAction.MultiWallet.AddBlockchains(primaryBlockchain))
|
||||
store.dispatch(WalletAction.MultiWallet.AddWalletManagers(primaryWalletManager))
|
||||
store.dispatch(WalletAction.MultiWallet.AddBlockchains(listOf(primaryBlockchain)))
|
||||
}
|
||||
store.dispatch(WalletAction.SetArtworkId(data.verifyResponse?.artworkInfo?.id))
|
||||
store.dispatch(WalletAction.LoadWallet(config.isTopUpEnabled))
|
||||
|
|
@ -177,6 +162,34 @@ class TapWalletManager {
|
|||
}
|
||||
}
|
||||
|
||||
private fun loadMultiWalletData(
|
||||
card: Card, primaryBlockchain: Blockchain, primaryWalletManager: WalletManager
|
||||
) {
|
||||
val presetTokens = primaryWalletManager.presetTokens.toList()
|
||||
val savedCurrencies = currenciesRepository.loadCardCurrencies(card.cardId)
|
||||
|
||||
if (savedCurrencies == null) {
|
||||
store.dispatch(WalletAction.MultiWallet.SaveCurrencies(
|
||||
CardCurrencies(
|
||||
blockchains = listOf(primaryBlockchain), tokens = presetTokens
|
||||
)))
|
||||
store.dispatch(WalletAction.MultiWallet.AddWalletManagers(primaryWalletManager))
|
||||
store.dispatch(WalletAction.MultiWallet.AddBlockchains(listOf(primaryBlockchain)))
|
||||
store.dispatch(WalletAction.MultiWallet.AddTokens(presetTokens))
|
||||
store.dispatch(WalletAction.MultiWallet.FindBlockchainsInUse(card, walletManagerFactory))
|
||||
store.dispatch(WalletAction.MultiWallet.FindTokensInUse)
|
||||
} else {
|
||||
val blockchains = listOf(primaryBlockchain) + savedCurrencies.blockchains
|
||||
val walletManagers = walletManagerFactory.makeWalletManagers(card, blockchains)
|
||||
val tokens = presetTokens + savedCurrencies.tokens
|
||||
|
||||
store.dispatch(WalletAction.MultiWallet.AddWalletManagers(walletManagers))
|
||||
store.dispatch(WalletAction.MultiWallet.AddBlockchains(blockchains))
|
||||
store.dispatch(WalletAction.MultiWallet.AddTokens(tokens))
|
||||
store.dispatch(WalletAction.MultiWallet.FindTokensInUse)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun reloadData(data: ScanNoteResponse) {
|
||||
withContext(Dispatchers.Main) {
|
||||
if (data.walletManager != null) {
|
||||
|
|
|
|||
|
|
@ -19,8 +19,11 @@ class CurrenciesRepository(val context: Application) {
|
|||
Types.newParameterizedType(List::class.java, Blockchain::class.java)
|
||||
)
|
||||
|
||||
fun loadCardCurrencies(cardId: String): CardCurrencies {
|
||||
return CardCurrencies(loadSavedTokens(cardId), loadSavedBlockchains(cardId))
|
||||
fun loadCardCurrencies(cardId: String): CardCurrencies? {
|
||||
val blockchains = loadSavedBlockchains(cardId)
|
||||
if (blockchains.isEmpty()) return null
|
||||
|
||||
return CardCurrencies(loadSavedTokens(cardId), blockchains)
|
||||
}
|
||||
|
||||
fun saveCardCurrencies(cardId: String, currencies: CardCurrencies) {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import com.tangem.tap.common.redux.NotificationAction
|
|||
import com.tangem.tap.common.redux.global.CryptoCurrencyName
|
||||
import com.tangem.tap.domain.TapError
|
||||
import com.tangem.tap.domain.configurable.warningMessage.WarningMessage
|
||||
import com.tangem.tap.domain.tokens.CardCurrencies
|
||||
import com.tangem.tap.domain.twins.TwinCardNumber
|
||||
import com.tangem.wallet.R
|
||||
import org.rekotlin.Action
|
||||
|
|
@ -32,29 +33,18 @@ sealed class WalletAction : Action {
|
|||
data class SetArtworkId(val artworkId: String?) : WalletAction()
|
||||
|
||||
|
||||
// sealed class ProcessWallet : WalletAction() {
|
||||
// data class LoadWallet(val artworkId: String?, val allowTopUp: Boolean
|
||||
// ) : ProcessWallet() {
|
||||
// data class Success(val wallet: Wallet) : ProcessWallet()
|
||||
// data class NoAccount(val wallet: Wallet, val amountToCreateAccount: String) : ProcessWallet()
|
||||
// data class Failure(val wallet: Wallet, val errorMessage: String? = null) : ProcessWallet()
|
||||
// }
|
||||
//
|
||||
// data class UpdateWallet(val currency: CryptoCurrencyName? = null) : ProcessWallet() {
|
||||
// object ScheduleUpdatingWallet : ProcessWallet()
|
||||
// data class Success(val wallet: Wallet) : ProcessWallet()
|
||||
// data class Failure(val errorMessage: String? = null) : ProcessWallet()
|
||||
// }
|
||||
// }
|
||||
|
||||
sealed class MultiWallet : WalletAction() {
|
||||
data class SetIsMultiwalletAllowed(val isMultiwalletAllowed: Boolean) : MultiWallet()
|
||||
data class AddWalletManagers(val walletManagers: List<WalletManager>) : MultiWallet()
|
||||
data class AddWalletManagers(val walletManagers: List<WalletManager>) : MultiWallet() {
|
||||
constructor(walletManager: WalletManager) : this(listOf(walletManager))
|
||||
}
|
||||
data class AddBlockchain(val blockchain: Blockchain) : MultiWallet()
|
||||
data class AddBlockchains(val blockchains: List<Blockchain>) : MultiWallet()
|
||||
data class AddTokens(val tokens: List<Token>) : MultiWallet()
|
||||
data class AddToken(val token: Token) : MultiWallet()
|
||||
data class SaveCurrencies(val cardCurrencies: CardCurrencies) : MultiWallet()
|
||||
object FindTokensInUse : MultiWallet()
|
||||
data class FindBlockchainsInUse(val card: Card, val factory: WalletManagerFactory) : MultiWallet()
|
||||
data class TokenLoaded(val amount: Amount) : MultiWallet()
|
||||
data class SelectWallet(val walletData: WalletData?) : MultiWallet()
|
||||
data class RemoveWallet(val walletData: WalletData) : MultiWallet()
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ data class WalletState(
|
|||
if (primaryWalletManager?.presetTokens?.find { it.symbol == currencyName } != null) {
|
||||
primaryWalletManager
|
||||
} else {
|
||||
null
|
||||
ethereumWalletManager
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
package com.tangem.tap.features.wallet.redux.middlewares
|
||||
|
||||
import com.tangem.blockchain.common.AmountType
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.Token
|
||||
import com.tangem.blockchain.common.TokenFinder
|
||||
import com.tangem.blockchain.extensions.Result
|
||||
import com.tangem.common.extensions.isZero
|
||||
import com.tangem.tap.common.redux.global.GlobalState
|
||||
import com.tangem.tap.common.redux.navigation.AppScreen
|
||||
import com.tangem.tap.common.redux.navigation.NavigationAction
|
||||
|
|
@ -13,6 +15,7 @@ import com.tangem.tap.features.wallet.redux.WalletState
|
|||
import com.tangem.tap.scope
|
||||
import com.tangem.tap.store
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
|
|
@ -40,12 +43,20 @@ class MultiWalletMiddleware {
|
|||
action.tokens.map { addToken(it, walletState) }
|
||||
}
|
||||
is WalletAction.MultiWallet.AddBlockchain -> {
|
||||
globalState?.scanNoteResponse?.card?.cardId?.let {
|
||||
currenciesRepository.saveAddedBlockchain(it, action.blockchain)
|
||||
globalState?.scanNoteResponse?.card?.let { card ->
|
||||
currenciesRepository.saveAddedBlockchain(card.cardId, action.blockchain)
|
||||
globalState.tapWalletManager.walletManagerFactory
|
||||
.makeWalletManager(card, action.blockchain)?.let {
|
||||
store.dispatch(WalletAction.MultiWallet.AddWalletManagers(it))
|
||||
}
|
||||
}
|
||||
store.dispatch(WalletAction.LoadFiatRate(currency = action.blockchain.currency))
|
||||
store.dispatch(WalletAction.LoadWallet(currency = action.blockchain.currency))
|
||||
}
|
||||
is WalletAction.MultiWallet.SaveCurrencies -> {
|
||||
val cardId = globalState?.scanNoteResponse?.card?.cardId
|
||||
cardId?.let { currenciesRepository.saveCardCurrencies(it, action.cardCurrencies) }
|
||||
}
|
||||
is WalletAction.MultiWallet.RemoveWallet -> {
|
||||
val cardId = globalState?.scanNoteResponse?.card?.cardId
|
||||
if (action.walletData.token != null) {
|
||||
|
|
@ -54,6 +65,36 @@ class MultiWalletMiddleware {
|
|||
cardId?.let { currenciesRepository.removeBlockchain(it, action.walletData.blockchain) }
|
||||
}
|
||||
}
|
||||
is WalletAction.MultiWallet.FindBlockchainsInUse -> {
|
||||
val blockchains = currenciesRepository.getBlockchains()
|
||||
.filterNot { walletState?.blockchains?.contains(it) == true }
|
||||
val walletManagers = action.factory.makeWalletManagers(action.card, blockchains)
|
||||
|
||||
scope.launch {
|
||||
walletManagers.map { walletManager ->
|
||||
async(Dispatchers.IO) {
|
||||
try {
|
||||
walletManager.update()
|
||||
val wallet = walletManager.wallet
|
||||
val coinAmount = wallet.amounts[AmountType.Coin]?.value
|
||||
if (coinAmount != null && !coinAmount.isZero()) {
|
||||
if (walletState?.getWalletData(wallet.blockchain.currency) == null) {
|
||||
scope.launch(Dispatchers.Main) {
|
||||
store.dispatch(WalletAction.MultiWallet.AddWalletManagers(
|
||||
listOfNotNull(walletManager)))
|
||||
store.dispatch(WalletAction.MultiWallet.AddBlockchain(
|
||||
wallet.blockchain
|
||||
))
|
||||
store.dispatch(WalletAction.LoadWallet.Success(wallet))
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (exception: Exception) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
is WalletAction.MultiWallet.FindTokensInUse -> {
|
||||
val walletManager = walletState?.getWalletManager(Blockchain.Ethereum.currency)
|
||||
?: return
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ class MultiWalletReducer {
|
|||
return when (action) {
|
||||
is WalletAction.MultiWallet.AddWalletManagers -> {
|
||||
state.copy(
|
||||
walletManagers = action.walletManagers
|
||||
walletManagers = state.walletManagers + action.walletManagers
|
||||
)
|
||||
}
|
||||
is WalletAction.MultiWallet.AddBlockchains -> {
|
||||
|
|
@ -160,6 +160,8 @@ class MultiWalletReducer {
|
|||
is WalletAction.MultiWallet.SetPrimaryToken ->
|
||||
state.copy(primaryToken = action.token)
|
||||
is WalletAction.MultiWallet.FindTokensInUse -> state
|
||||
is WalletAction.MultiWallet.FindBlockchainsInUse -> state
|
||||
is WalletAction.MultiWallet.SaveCurrencies -> state
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -125,14 +125,11 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
|
|||
val wallets = newState.replaceSomeWallets(newWallets)
|
||||
newState = newState.copy(wallets = wallets)
|
||||
}
|
||||
|
||||
}
|
||||
is WalletAction.LoadWallet.Success -> newState = onWalletLoadedReducer.reduce(action.wallet, newState)
|
||||
is WalletAction.UpdateWallet.Success -> {
|
||||
newState = onWalletLoadedReducer.reduce(action.wallet, newState)
|
||||
// newState = newState.copy(updatingWallet = newState.pendingTransactions.isNotEmpty())
|
||||
}
|
||||
|
||||
is WalletAction.LoadWallet.NoAccount -> {
|
||||
val walletData = newState.getWalletData(action.wallet.blockchain.currency)?.copy(
|
||||
currencyData = BalanceWidgetData(
|
||||
|
|
@ -193,21 +190,6 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
|
|||
newState = newState.copy(cardImage = cardImage)
|
||||
}
|
||||
|
||||
// is WalletAction.UpdateWallet -> {
|
||||
// if (store.state.walletState.state == ProgressState.Done) {
|
||||
// newState = newState.copy(updatingWallet = true)
|
||||
// }
|
||||
// }
|
||||
// is WalletAction.UpdateWallet.ScheduleUpdatingWallet ->
|
||||
// newState = newState.copy(updatingWallet = true)
|
||||
|
||||
// is WalletAction.UpdateWallet.Failure -> newState = newState.copy(updatingWallet = false)
|
||||
// is WalletAction.LoadFiatRate -> {
|
||||
// newState.copy(currencyData = newState.currencyData.copy(
|
||||
// fiatAmount = null,
|
||||
// token = newState.currencyData.token?.copy(fiatAmount = null))
|
||||
// )
|
||||
// }
|
||||
is WalletAction.LoadFiatRate.Success ->
|
||||
newState = setNewFiatRate(action.fiatRate, state.globalState.appCurrency, newState)
|
||||
is WalletAction.LoadArtwork -> {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue