Updated on 2026-08-14
This commit is contained in:
parent
0835b34e97
commit
de03cc28b6
3 changed files with 77 additions and 29 deletions
|
|
@ -34,6 +34,7 @@ data class WalletState(
|
|||
val mainWarningsList: List<WarningMessage> = mutableListOf(),
|
||||
val wallets: List<WalletData> = emptyList(),
|
||||
val walletManagers: List<WalletManager> = emptyList(),
|
||||
val walletManagersThrottling: MutableMap<Blockchain, Long> = mutableMapOf(),
|
||||
val isMultiwalletAllowed: Boolean = false,
|
||||
val cardCurrency: CryptoCurrencyName? = null,
|
||||
val selectedWallet: Currency? = null,
|
||||
|
|
@ -54,8 +55,8 @@ data class WalletState(
|
|||
val primaryWallet = if (wallets.isNotEmpty()) wallets[0] else null
|
||||
|
||||
val shouldShowDetails: Boolean =
|
||||
primaryWallet?.currencyData?.status != BalanceStatus.EmptyCard &&
|
||||
primaryWallet?.currencyData?.status != BalanceStatus.UnknownBlockchain
|
||||
primaryWallet?.currencyData?.status != BalanceStatus.EmptyCard &&
|
||||
primaryWallet?.currencyData?.status != BalanceStatus.UnknownBlockchain
|
||||
|
||||
val blockchains: List<Blockchain>
|
||||
get() = walletManagers.map { it.wallet.blockchain }
|
||||
|
|
@ -63,6 +64,8 @@ data class WalletState(
|
|||
val currencies: List<Currency>
|
||||
get() = wallets.mapNotNull { it.currency }
|
||||
|
||||
val throttlingDuration = 10000L
|
||||
|
||||
fun getWalletManager(token: Token?): WalletManager? {
|
||||
if (token == null) return null
|
||||
return walletManagers.find { it.wallet.blockchain == token.blockchain }
|
||||
|
|
@ -101,10 +104,10 @@ data class WalletState(
|
|||
|
||||
if (!isPrimaryCurrency(walletData)) {
|
||||
val walletManager = getWalletManager(walletData.currency)
|
||||
?: return true
|
||||
?: return true
|
||||
|
||||
if (walletData.currency is Currency.Blockchain &&
|
||||
walletManager.cardTokens.isNotEmpty()
|
||||
walletManager.cardTokens.isNotEmpty()
|
||||
) {
|
||||
return false
|
||||
}
|
||||
|
|
@ -113,22 +116,22 @@ data class WalletState(
|
|||
|
||||
if (walletData.currency is Currency.Blockchain) {
|
||||
return wallet.recentTransactions.toPendingTransactions(wallet.address).isEmpty() &&
|
||||
wallet.amounts.toSendableAmounts().isEmpty()
|
||||
wallet.amounts.toSendableAmounts().isEmpty()
|
||||
} else if (walletData.currency is Currency.Token) (
|
||||
return wallet.recentTransactions.toPendingTransactionsForToken(
|
||||
walletData.currency.token, wallet.address).isEmpty()
|
||||
&& wallet.amounts[AmountType.Token(token = walletData.currency.token)]
|
||||
?.isAboveZero() != true
|
||||
)
|
||||
return wallet.recentTransactions.toPendingTransactionsForToken(
|
||||
walletData.currency.token, wallet.address).isEmpty()
|
||||
&& wallet.amounts[AmountType.Token(token = walletData.currency.token)]
|
||||
?.isAboveZero() != true
|
||||
)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun isPrimaryCurrency(walletData: WalletData): Boolean {
|
||||
return (walletData.currency is Currency.Blockchain &&
|
||||
walletData.currency.blockchain == store.state.walletState.primaryBlockchain)
|
||||
|| (walletData.currency is Currency.Token &&
|
||||
walletData.currency.token == store.state.walletState.primaryToken)
|
||||
walletData.currency.blockchain == store.state.walletState.primaryBlockchain)
|
||||
|| (walletData.currency is Currency.Token &&
|
||||
walletData.currency.token == store.state.walletState.primaryToken)
|
||||
}
|
||||
|
||||
fun replaceWalletInWallets(walletData: WalletData?): List<WalletData> {
|
||||
|
|
@ -149,7 +152,7 @@ data class WalletState(
|
|||
val remainingWallets: MutableList<WalletData> = newWallets.toMutableList()
|
||||
val updatedWallets = wallets.map { wallet ->
|
||||
val newWallet = newWallets
|
||||
.firstOrNull { wallet.currency == it.currency }
|
||||
.firstOrNull { wallet.currency == it.currency }
|
||||
if (newWallet == null) {
|
||||
wallet
|
||||
} else {
|
||||
|
|
@ -176,9 +179,15 @@ data class WalletState(
|
|||
|
||||
fun addWalletManagers(newWalletManagers: List<WalletManager>): WalletState {
|
||||
val updatedWalletManagers = this.walletManagers +
|
||||
newWalletManagers.filterNot { this.blockchains.contains(it.wallet.blockchain) }
|
||||
newWalletManagers.filterNot { this.blockchains.contains(it.wallet.blockchain) }
|
||||
return copy(walletManagers = updatedWalletManagers)
|
||||
}
|
||||
|
||||
fun isThrottling(walletManager: WalletManager): Boolean {
|
||||
val inThrottlingUpTo = walletManagersThrottling[walletManager.wallet.blockchain] ?: return false
|
||||
val diff = System.currentTimeMillis() - inThrottlingUpTo
|
||||
return diff < 0
|
||||
}
|
||||
}
|
||||
|
||||
sealed class WalletDialog : StateDialog {
|
||||
|
|
|
|||
|
|
@ -29,9 +29,7 @@ import com.tangem.tap.network.NetworkStateChanged
|
|||
import com.tangem.tap.scope
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.tap.tangemSdkManager
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.*
|
||||
import org.rekotlin.Action
|
||||
import org.rekotlin.DispatchFunction
|
||||
import org.rekotlin.Middleware
|
||||
|
|
@ -61,14 +59,32 @@ class WalletMiddleware {
|
|||
is WalletAction.Warnings -> warningsMiddleware.handle(action, globalState)
|
||||
is WalletAction.MultiWallet -> multiWalletMiddleware.handle(action, walletState, globalState)
|
||||
is WalletAction.LoadWallet -> {
|
||||
scope.launch {
|
||||
if (action.blockchain == null) {
|
||||
walletState.walletManagers.map { walletManager ->
|
||||
async { globalState.tapWalletManager.loadWalletData(walletManager) }
|
||||
}.awaitAll()
|
||||
} else {
|
||||
val walletManager = walletState.getWalletManager(action.blockchain)
|
||||
walletManager?.let { globalState.tapWalletManager.loadWalletData(it) }
|
||||
if (action.blockchain == null) {
|
||||
val throttledWalletManagers = walletState.walletManagers.filter { walletState.isThrottling(it) }
|
||||
val freeWalletManagers = walletState.walletManagers.filter { !walletState.isThrottling(it) }
|
||||
scope.launch {
|
||||
freeWalletManagers.map { walletManager ->
|
||||
async { globalState.tapWalletManager.loadWalletData(walletManager) }
|
||||
}.awaitAll()
|
||||
|
||||
delay(500)
|
||||
launch(Dispatchers.Main) {
|
||||
throttledWalletManagers.forEach { store.dispatch(WalletAction.LoadWallet.Success(it.wallet)) }
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
val walletManager = walletState.getWalletManager(action.blockchain) ?: return
|
||||
|
||||
scope.launch {
|
||||
if (walletState.isThrottling(walletManager)) {
|
||||
delay(500)
|
||||
launch(Dispatchers.Main) {
|
||||
store.dispatch(WalletAction.LoadWallet.Success(walletManager.wallet))
|
||||
}
|
||||
} else {
|
||||
globalState.tapWalletManager.loadWalletData(walletManager)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -230,12 +246,12 @@ class WalletMiddleware {
|
|||
when (currency) {
|
||||
is Currency.Blockchain -> {
|
||||
val amountToSend = amounts?.find { it.currencySymbol == currency.blockchain.currency }
|
||||
?: return WalletAction.Send.ChooseCurrency(amounts)
|
||||
?: return WalletAction.Send.ChooseCurrency(amounts)
|
||||
PrepareSendScreen(amountToSend, selectedWalletData.fiatRate, walletManager)
|
||||
}
|
||||
is Currency.Token -> {
|
||||
val amountToSend = amounts?.find { it.currencySymbol == currency.token.symbol }
|
||||
?: return WalletAction.Send.ChooseCurrency(amounts)
|
||||
?: return WalletAction.Send.ChooseCurrency(amounts)
|
||||
prepareSendActionForToken(amountToSend, state, selectedWalletData, wallet, walletManager)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,8 +94,20 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
|
|||
}
|
||||
is WalletAction.LoadWallet -> {
|
||||
if (action.blockchain == null) {
|
||||
val wallets = newState.wallets.map { wallet ->
|
||||
// update throttling
|
||||
val updatedThrottling = newState.walletManagersThrottling
|
||||
newState.walletManagers.forEach {
|
||||
val now = System.currentTimeMillis()
|
||||
val currentThrottling = newState.walletManagersThrottling[it.wallet.blockchain] ?: 0L
|
||||
if (currentThrottling == 0L || currentThrottling < now) {
|
||||
val newThrottlingUpTo = now + newState.throttlingDuration
|
||||
updatedThrottling[it.wallet.blockchain] = newThrottlingUpTo
|
||||
}
|
||||
|
||||
}
|
||||
newState = newState.copy(walletManagersThrottling = updatedThrottling)
|
||||
|
||||
val wallets = newState.wallets.map { wallet ->
|
||||
wallet.copy(
|
||||
currencyData = wallet.currencyData.copy(
|
||||
status = BalanceStatus.Loading,
|
||||
|
|
@ -113,6 +125,17 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
|
|||
} else {
|
||||
val walletManager = newState.getWalletManager(action.blockchain) ?: return newState
|
||||
val blockchain = walletManager.wallet.blockchain
|
||||
|
||||
// update throttling
|
||||
val now = System.currentTimeMillis()
|
||||
val currentThrottling = newState.walletManagersThrottling[blockchain] ?: 0L
|
||||
if (currentThrottling == 0L || currentThrottling < now) {
|
||||
val newThrottlingUpTo = now + newState.throttlingDuration
|
||||
val newMap = newState.walletManagersThrottling.toMutableMap()
|
||||
newMap[blockchain] = newThrottlingUpTo
|
||||
newState = newState.copy(walletManagersThrottling = newMap)
|
||||
}
|
||||
|
||||
val currencies = listOf(Currency.Blockchain(blockchain)) +
|
||||
walletManager.cardTokens.map { Currency.Token(it) }
|
||||
val newWallets = newState.wallets.filter { currencies.contains(it.currency) }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue