Updated on 2026-08-14

This commit is contained in:
Tangem 2021-10-22 00:15:34 +03:00
parent 7379f3555a
commit bcfca80f54

View file

@ -26,6 +26,7 @@ import com.tangem.tap.features.wallet.redux.*
import com.tangem.tap.network.NetworkStateChanged
import kotlinx.coroutines.launch
import org.rekotlin.Action
import org.rekotlin.DispatchFunction
import org.rekotlin.Middleware
class WalletMiddleware {
@ -37,180 +38,173 @@ class WalletMiddleware {
val walletMiddleware: Middleware<AppState> = { dispatch, state ->
{ next ->
{ action ->
val globalState = state()?.globalState
val walletState = state()?.walletState
when (action) {
is WalletAction.TradeCryptoAction -> tradeCryptoMiddleware.handle(action)
is WalletAction.TwinsAction -> twinsMiddleware.handle(action)
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 ->
globalState?.tapWalletManager?.loadWalletData(walletManager)
}
} else {
val walletManager = walletState?.getWalletManager(action.blockchain)
walletManager?.let { globalState?.tapWalletManager?.loadWalletData(it) }
}
}
}
is WalletAction.LoadWallet.Success -> {
val coinAmount = action.wallet.amounts[AmountType.Coin]?.value
if (coinAmount != null && !coinAmount.isZero()) {
if (walletState?.getWalletData(action.wallet.blockchain) == null) {
store.dispatch(WalletAction.MultiWallet.AddBlockchain(action.wallet.blockchain))
store.dispatch(WalletAction.LoadWallet.Success(action.wallet))
}
}
store.dispatch(WalletAction.Warnings.CheckHashesCount.CheckHashesCountOnline)
warningsMiddleware.tryToShowAppRatingWarning(action.wallet)
}
is WalletAction.LoadFiatRate -> {
scope.launch {
when {
action.wallet != null -> {
globalState?.tapWalletManager?.loadFiatRate(
globalState.appCurrency, action.wallet
)
}
action.currency != null -> {
globalState?.tapWalletManager?.loadFiatRate(
globalState.appCurrency, action.currency
)
}
else -> {
globalState?.tapWalletManager?.loadFiatRate(
fiatCurrency = globalState.appCurrency,
currencies = walletState?.wallets?.mapNotNull { it.currency }
?: emptyList()
)
}
}
}
}
is WalletAction.CreateWallet -> {
if (walletState?.twinCardsState != null) {
val cardId = globalState?.scanResponse?.card?.cardId
val twinCardNumber = cardId?.let { TwinsHelper.getTwinCardNumber(it) }
store.dispatch(
CreateTwinWalletAction.ShowWarning(twinCardNumber, CreateTwinWallet.CreateWallet)
)
} else {
scope.launch {
val result = tangemSdkManager.createWallet(
globalState?.scanResponse?.card?.cardId
)
when (result) {
is CompletionResult.Success -> {
val scanNoteResponse =
globalState?.scanResponse?.copy(card = result.data)
scanNoteResponse?.let {
globalState.tapWalletManager.onCardScanned(scanNoteResponse)
}
}
is CompletionResult.Failure -> {
(result.error as? TangemSdkError)?.let { error ->
FirebaseAnalyticsHandler.logCardSdkError(
error,
FirebaseAnalyticsHandler.ActionToLog.CreateWallet,
card = store.state.detailsState.card
)
}
}
}
}
}
}
is WalletAction.UpdateWallet -> {
if (action.blockchain != null) {
scope.launch {
val walletManager = walletState?.getWalletManager(action.blockchain)
walletManager?.let { globalState?.tapWalletManager?.updateWallet(it) }
}
} else {
scope.launch {
if (walletState?.state == ProgressState.Done) {
walletState.walletManagers.map { walletManager ->
globalState?.tapWalletManager?.updateWallet(walletManager)
}
}
}
}
handleAction(action, dispatch)
next(action)
}
}
}
private fun handleAction(action: Action, dispatch: DispatchFunction) {
val globalState = store.state.globalState
val walletState = store.state.walletState
when (action) {
is WalletAction.TradeCryptoAction -> tradeCryptoMiddleware.handle(action)
is WalletAction.TwinsAction -> twinsMiddleware.handle(action)
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 ->
globalState.tapWalletManager.loadWalletData(walletManager)
}
} else {
val walletManager = walletState.getWalletManager(action.blockchain)
walletManager?.let { globalState.tapWalletManager.loadWalletData(it) }
}
is WalletAction.Scan -> {
store.dispatch(HomeAction.ShouldScanCardOnResume(true))
store.dispatch(NavigationAction.PopBackTo(AppScreen.Home))
}
}
is WalletAction.LoadWallet.Success -> {
val coinAmount = action.wallet.amounts[AmountType.Coin]?.value
if (coinAmount != null && !coinAmount.isZero()) {
if (walletState.getWalletData(action.wallet.blockchain) == null) {
store.dispatch(WalletAction.MultiWallet.AddBlockchain(action.wallet.blockchain))
store.dispatch(WalletAction.LoadWallet.Success(action.wallet))
}
is WalletAction.LoadCardInfo -> {
scope.launch {
val response = OnlineCardVerifier().getCardInfo(
action.card.cardId, action.card.cardPublicKey
}
store.dispatch(WalletAction.Warnings.CheckHashesCount.CheckHashesCountOnline)
warningsMiddleware.tryToShowAppRatingWarning(action.wallet)
}
is WalletAction.LoadFiatRate -> {
scope.launch {
when {
action.wallet != null -> {
globalState.tapWalletManager.loadFiatRate(
globalState.appCurrency, action.wallet
)
when (response) {
is Result.Success -> {
store.dispatchOnMain(
WalletAction.SetArtworkId(response.data.artwork?.id)
)
store.dispatchOnMain(
WalletAction.LoadArtwork(action.card, response.data.artwork?.id)
)
store.dispatchOnMain(
GlobalAction.SetIfCardVerifiedOnline(response.data.passed)
)
}
is Result.Failure -> {
store.dispatchOnMain(
GlobalAction.SetIfCardVerifiedOnline(false)
)
}
}
store.dispatchOnMain(WalletAction.Warnings.CheckIfNeeded)
}
}
is WalletAction.LoadData -> {
scope.launch {
val scanNoteResponse = globalState?.scanResponse
?: return@launch
if (!walletState?.wallets.isNullOrEmpty()) {
globalState.tapWalletManager.reloadData(scanNoteResponse)
} else {
globalState.tapWalletManager.loadData(scanNoteResponse)
}
action.currency != null -> {
globalState.tapWalletManager.loadFiatRate(
globalState.appCurrency, action.currency
)
}
}
is NetworkStateChanged -> {
globalState?.scanResponse?.let { scanNoteResponse ->
store.dispatch(WalletAction.Warnings.CheckHashesCount.CheckHashesCountOnline)
scope.launch {
globalState.tapWalletManager.loadData(scanNoteResponse)
}
}
}
is WalletAction.CopyAddress -> {
action.context.copyToClipboard(action.address)
store.dispatch(WalletAction.CopyAddress.Success)
}
is WalletAction.ShareAddress -> {
action.context.shareText(action.address)
}
is WalletAction.ExploreAddress -> {
val uri = Uri.parse(action.exploreUrl)
val intent = Intent(Intent.ACTION_VIEW, uri)
ContextCompat.startActivity(action.context, intent, null)
}
is WalletAction.Send -> {
val newAction = prepareSendAction(action.amount, state()?.walletState)
store.dispatch(newAction)
if (newAction is PrepareSendScreen) {
store.dispatch(NavigationAction.NavigateTo(AppScreen.Send))
else -> {
globalState.tapWalletManager.loadFiatRate(
fiatCurrency = globalState.appCurrency,
currencies = walletState.wallets.mapNotNull { it.currency }
)
}
}
}
next(action)
}
is WalletAction.CreateWallet -> {
if (walletState.twinCardsState != null) {
val cardId = globalState.scanResponse?.card?.cardId
val twinCardNumber = cardId?.let { TwinsHelper.getTwinCardNumber(it) }
store.dispatch(
CreateTwinWalletAction.ShowWarning(twinCardNumber, CreateTwinWallet.CreateWallet)
)
} else {
scope.launch {
val result = tangemSdkManager.createWallet(
globalState.scanResponse?.card?.cardId
)
when (result) {
is CompletionResult.Success -> {
val scanNoteResponse = globalState.scanResponse?.copy(card = result.data)
scanNoteResponse?.let {
globalState.tapWalletManager.onCardScanned(scanNoteResponse)
}
}
is CompletionResult.Failure -> {
(result.error as? TangemSdkError)?.let { error ->
FirebaseAnalyticsHandler.logCardSdkError(
error,
FirebaseAnalyticsHandler.ActionToLog.CreateWallet,
card = store.state.detailsState.card
)
}
}
}
}
}
}
is WalletAction.UpdateWallet -> {
if (action.blockchain != null) {
scope.launch {
val walletManager = walletState.getWalletManager(action.blockchain)
walletManager?.let { globalState.tapWalletManager.updateWallet(it) }
}
} else {
scope.launch {
if (walletState.state == ProgressState.Done) {
walletState.walletManagers.map { walletManager ->
globalState.tapWalletManager.updateWallet(walletManager)
}
}
}
}
}
is WalletAction.Scan -> {
store.dispatch(HomeAction.ShouldScanCardOnResume(true))
store.dispatch(NavigationAction.PopBackTo(AppScreen.Home))
}
is WalletAction.LoadCardInfo -> {
scope.launch {
val response = OnlineCardVerifier().getCardInfo(
action.card.cardId, action.card.cardPublicKey
)
when (response) {
is Result.Success -> {
val actionList = listOf(
WalletAction.SetArtworkId(response.data.artwork?.id),
WalletAction.LoadArtwork(action.card, response.data.artwork?.id),
GlobalAction.SetIfCardVerifiedOnline(response.data.passed)
)
actionList.forEach { store.dispatch(it) }
}
is Result.Failure -> {
store.dispatchOnMain(GlobalAction.SetIfCardVerifiedOnline(false))
}
}
store.dispatchOnMain(WalletAction.Warnings.CheckIfNeeded)
}
}
is WalletAction.LoadData -> {
scope.launch {
val scanNoteResponse = globalState.scanResponse ?: return@launch
if (!walletState.wallets.isEmpty()) {
globalState.tapWalletManager.reloadData(scanNoteResponse)
} else {
globalState.tapWalletManager.loadData(scanNoteResponse)
}
}
}
is NetworkStateChanged -> {
globalState.scanResponse?.let { scanNoteResponse ->
store.dispatch(WalletAction.Warnings.CheckHashesCount.CheckHashesCountOnline)
scope.launch { globalState.tapWalletManager.loadData(scanNoteResponse) }
}
}
is WalletAction.CopyAddress -> {
action.context.copyToClipboard(action.address)
store.dispatch(WalletAction.CopyAddress.Success)
}
is WalletAction.ShareAddress -> {
action.context.shareText(action.address)
}
is WalletAction.ExploreAddress -> {
val uri = Uri.parse(action.exploreUrl)
val intent = Intent(Intent.ACTION_VIEW, uri)
ContextCompat.startActivity(action.context, intent, null)
}
is WalletAction.Send -> {
val newAction = prepareSendAction(action.amount, store.state.walletState)
store.dispatch(newAction)
if (newAction is PrepareSendScreen) {
store.dispatch(NavigationAction.NavigateTo(AppScreen.Send))
}
}
}
}