diff --git a/app/src/main/java/com/tangem/tap/common/extensions/WalletManager.kt b/app/src/main/java/com/tangem/tap/common/extensions/WalletManager.kt index 58284b0cc0..311932f7c1 100644 --- a/app/src/main/java/com/tangem/tap/common/extensions/WalletManager.kt +++ b/app/src/main/java/com/tangem/tap/common/extensions/WalletManager.kt @@ -51,11 +51,10 @@ suspend fun WalletManager.safeUpdate(): Result = try { fun WalletManager?.getToUpUrl(): String? { val globalState = store.state.globalState - val exchangeManager = globalState.exchangeManager ?: return null val wallet = this?.wallet ?: return null val defaultAddress = wallet.address - return exchangeManager.getUrl( + return globalState.exchangeManager.getUrl( action = CurrencyExchangeManager.Action.Buy, blockchain = wallet.blockchain, cryptoCurrencyName = wallet.blockchain.currency, diff --git a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalState.kt b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalState.kt index 62e5217866..1fed436b47 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalState.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalState.kt @@ -25,7 +25,7 @@ data class GlobalState( val appCurrency: FiatCurrency = FiatCurrency.Default, val scanCardFailsCounter: Int = 0, val dialog: StateDialog? = null, - val exchangeManager: CurrencyExchangeManager? = null, + val exchangeManager: CurrencyExchangeManager = CurrencyExchangeManager.dummy(), val resources: AndroidResources = AndroidResources(), val analyticsHandlers: AnalyticsHandler? = null, val userCountryCode: String? = null, diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/note/redux/OnboardingNoteState.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/note/redux/OnboardingNoteState.kt index a9ebb0e757..ae7a2db594 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/note/redux/OnboardingNoteState.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/note/redux/OnboardingNoteState.kt @@ -26,7 +26,7 @@ data class OnboardingNoteState( get() = steps.indexOf(currentStep) val isBuyAllowed: Boolean by ReadOnlyProperty { _, _ -> - store.state.globalState.exchangeManager?.availableForBuy(walletBalance.currency) ?: false + store.state.globalState.exchangeManager.availableForBuy(walletBalance.currency) } } diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsState.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsState.kt index 19cc8ad307..0b2e4b4d1a 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsState.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsState.kt @@ -56,7 +56,7 @@ data class TwinCardsState( get() = currentStep == TwinCardsStep.CreateSecondWallet || currentStep == TwinCardsStep.CreateThirdWallet val isBuyAllowed: Boolean by ReadOnlyProperty { _, _ -> - store.state.globalState.exchangeManager?.availableForBuy(walletBalance.currency) ?: false + store.state.globalState.exchangeManager.availableForBuy(walletBalance.currency) } } diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt index ec3107b151..891b07a3fd 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt @@ -7,9 +7,6 @@ import com.tangem.blockchain.common.Wallet import com.tangem.blockchain.common.WalletManager import com.tangem.blockchain.common.address.AddressType import com.tangem.common.extensions.isZero -import com.tangem.domain.common.extensions.canHandleToken -import com.tangem.domain.common.extensions.toCoinId -import com.tangem.domain.features.addCustomToken.CustomCurrency import com.tangem.tap.common.entities.Button import com.tangem.tap.common.extensions.toQrCode import com.tangem.tap.common.redux.global.CryptoCurrencyName @@ -17,12 +14,18 @@ import com.tangem.tap.common.toggleWidget.WidgetState import com.tangem.tap.domain.configurable.warningMessage.WarningMessage import com.tangem.tap.domain.tokens.models.BlockchainNetwork import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsState -import com.tangem.tap.features.wallet.models.* +import com.tangem.tap.features.wallet.models.Currency +import com.tangem.tap.features.wallet.models.PendingTransaction +import com.tangem.tap.features.wallet.models.TotalBalance +import com.tangem.tap.features.wallet.models.WalletRent +import com.tangem.tap.features.wallet.models.WalletWarning +import com.tangem.tap.features.wallet.models.hasPendingTransactions +import com.tangem.tap.features.wallet.models.hasSendableAmounts +import com.tangem.tap.features.wallet.models.isSendableAmount import com.tangem.tap.features.wallet.redux.reducers.calculateTotalFiatAmount import com.tangem.tap.features.wallet.redux.reducers.findProgressState import com.tangem.tap.features.wallet.ui.BalanceStatus import com.tangem.tap.features.wallet.ui.BalanceWidgetData -import com.tangem.tap.network.exchangeServices.CurrencyExchangeManager import com.tangem.tap.store import org.rekotlin.StateType import java.math.BigDecimal @@ -248,32 +251,6 @@ data class WalletState( return updatedWallets + remainingWallets } - fun updateTradeCryptoState( - exchangeManager: CurrencyExchangeManager?, - walletData: WalletData - ): WalletData { - return walletData.copy( - tradeCryptoState = TradeCryptoState.from( - exchangeManager, - walletData - ) - ) - } - - fun updateTradeCryptoState( - exchangeManager: CurrencyExchangeManager?, - walletDataList: List - ): List { - return walletDataList.map { - it.copy( - tradeCryptoState = TradeCryptoState.from( - exchangeManager, - it - ) - ) - } - } - private fun updateTotalBalance(): WalletState { val walletsData = this.wallets .flatMap(WalletStore::walletsData) @@ -352,39 +329,24 @@ data class Artwork( } } -data class TradeCryptoState( - val isAvailableToSell: () -> Boolean = { false }, - val isAvailableToBuy: () -> Boolean = { false }, -) { - companion object { - fun from( - exchangeManager: CurrencyExchangeManager?, - walletData: WalletData - ): TradeCryptoState { - val exchanger = exchangeManager ?: return walletData.tradeCryptoState - val currency = walletData.currency - - return TradeCryptoState( - isAvailableToSell = { exchanger.availableForSell(currency) }, - isAvailableToBuy = { exchanger.availableForBuy(currency) }, - ) - } - } -} - data class WalletData( val pendingTransactions: List = emptyList(), val hashesCountVerified: Boolean? = null, val walletAddresses: WalletAddresses? = null, val currencyData: BalanceWidgetData = BalanceWidgetData(), val updatingWallet: Boolean = false, - val tradeCryptoState: TradeCryptoState = TradeCryptoState(), val fiatRateString: String? = null, val fiatRate: BigDecimal? = null, val mainButton: WalletMainButton = WalletMainButton.SendButton(false), val currency: Currency, val walletRent: WalletRent? = null, ) { + val isAvailableToBuy: Boolean + get() = store.state.globalState.exchangeManager.availableForBuy(currency) + + val isAvailableToSell: Boolean + get() = store.state.globalState.exchangeManager.availableForSell(currency) + fun shouldShowMultipleAddress(): Boolean { val listOfAddresses = walletAddresses?.list ?: return false return listOfAddresses.size > 1 diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/TradeCryptoMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/TradeCryptoMiddleware.kt index 064647d863..319c940a52 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/TradeCryptoMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/TradeCryptoMiddleware.kt @@ -37,20 +37,18 @@ class TradeCryptoMiddleware { action: WalletAction.TradeCryptoAction.Buy, ) { if (action.checkUserLocation && state()?.globalState?.userCountryCode == RUSSIA_COUNTRY_CODE) { - store.dispatchOnMain( - WalletAction.DialogAction.RussianCardholdersWarningDialog - ) + store.dispatchOnMain(WalletAction.DialogAction.RussianCardholdersWarningDialog) return } val selectedWalletData = store.state.walletState.getSelectedWalletData() ?: return - val exchangeManager = store.state.globalState.exchangeManager ?: return val card = store.state.globalState.scanResponse?.card ?: return - val appCurrency = store.state.globalState.appCurrency val addresses = selectedWalletData.walletAddresses?.list.orEmpty() if (addresses.isEmpty()) return + val exchangeManager = store.state.globalState.exchangeManager + val appCurrency = store.state.globalState.appCurrency val currency = selectedWalletData.currency if (currency is Currency.Token && currency.blockchain.isTestnet()) { @@ -81,15 +79,13 @@ class TradeCryptoMiddleware { private fun proceedSellAction() { val selectedWalletData = store.state.walletState.getSelectedWalletData() ?: return - val exchangeManager = store.state.globalState.exchangeManager ?: return - val appCurrency = store.state.globalState.appCurrency + val appCurrency = store.state.globalState.appCurrency val addresses = selectedWalletData.walletAddresses?.list.orEmpty() if (addresses.isEmpty()) return val currency = selectedWalletData.currency - - exchangeManager.getUrl( + store.state.globalState.exchangeManager.getUrl( action = CurrencyExchangeManager.Action.Sell, blockchain = currency.blockchain, cryptoCurrencyName = currency.currencySymbol, @@ -100,8 +96,8 @@ class TradeCryptoMiddleware { private fun preconfigureAndOpenSendScreen(action: WalletAction.TradeCryptoAction.SendCrypto) { val selectedWalletData = store.state.walletState.getSelectedWalletData() ?: return - val walletManager = - store.state.walletState.getWalletManager(selectedWalletData.currency) + + val walletManager = store.state.walletState.getWalletManager(selectedWalletData.currency) store.dispatchOnMain(PrepareSendScreen( coinAmount = walletManager?.wallet?.amounts?.get(AmountType.Coin), coinRate = selectedWalletData.fiatRate, @@ -116,11 +112,10 @@ class TradeCryptoMiddleware { } private fun openReceiptUrl(transactionId: String) { - val exchangeManager = store.state.globalState.exchangeManager ?: return - store.dispatchOnMain(NavigationAction.PopBackTo()) - exchangeManager.getSellCryptoReceiptUrl(CurrencyExchangeManager.Action.Sell, transactionId)?.let { - store.dispatchOnMain(NavigationAction.OpenUrl(it)) - } + store.state.globalState.exchangeManager.getSellCryptoReceiptUrl( + action = CurrencyExchangeManager.Action.Sell, + transactionId = transactionId, + )?.let { store.dispatchOnMain(NavigationAction.OpenUrl(it)) } } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/OnWalletLoadedReducer.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/OnWalletLoadedReducer.kt index 482285de76..63d378718f 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/OnWalletLoadedReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/OnWalletLoadedReducer.kt @@ -13,7 +13,9 @@ import com.tangem.tap.features.wallet.models.Currency import com.tangem.tap.features.wallet.models.filterByToken import com.tangem.tap.features.wallet.models.getPendingTransactions import com.tangem.tap.features.wallet.models.removeUnknownTransactions -import com.tangem.tap.features.wallet.redux.* +import com.tangem.tap.features.wallet.redux.ProgressState +import com.tangem.tap.features.wallet.redux.WalletMainButton +import com.tangem.tap.features.wallet.redux.WalletState import com.tangem.tap.features.wallet.redux.WalletState.Companion.UNKNOWN_AMOUNT_SIGN import com.tangem.tap.features.wallet.ui.BalanceStatus import com.tangem.tap.features.wallet.ui.BalanceWidgetData @@ -38,8 +40,6 @@ class OnWalletLoadedReducer { val walletData = walletState.getWalletData(blockchainNetwork) ?: return walletState val fiatCurrency = store.state.globalState.appCurrency - val exchangeManager = store.state.globalState.exchangeManager - val coinAmountValue = wallet.amounts[AmountType.Coin]?.value val formattedAmount = coinAmountValue?.toFormattedCurrencyString( wallet.blockchain.decimals(), @@ -71,7 +71,6 @@ class OnWalletLoadedReducer { pendingTransactions = pendingTransactions.removeUnknownTransactions(), mainButton = WalletMainButton.SendButton(isCoinSendButtonEnabled), currency = Currency.fromBlockchainNetwork(blockchainNetwork), - tradeCryptoState = TradeCryptoState.from(exchangeManager, walletData), ) val tokens = wallet.getTokens().mapNotNull { token -> @@ -104,7 +103,6 @@ class OnWalletLoadedReducer { ), pendingTransactions = tokenPendingTransactions.removeUnknownTransactions(), mainButton = WalletMainButton.SendButton(isTokenSendButtonEnabled), - tradeCryptoState = TradeCryptoState.from(exchangeManager, tokenWalletData), ) } val newWallets = tokens + newWalletData @@ -118,8 +116,6 @@ class OnWalletLoadedReducer { if (wallet.blockchain != walletState.primaryBlockchain) return walletState val fiatCurrencyName = store.state.globalState.appCurrency.code - val exchangeManager = store.state.globalState.exchangeManager - val token = wallet.getFirstToken() val tokenData = if (token != null) { val tokenAmount = wallet.getTokenAmount(token) @@ -167,7 +163,6 @@ class OnWalletLoadedReducer { ), pendingTransactions = pendingTransactions.removeUnknownTransactions(), mainButton = WalletMainButton.SendButton(sendButtonEnabled), - tradeCryptoState = TradeCryptoState.from(exchangeManager, walletState.primaryWallet), ) val wallets = listOfNotNull(walletData) val updatedStore = walletState.getWalletStore(walletData?.currency)?.updateWallets(wallets) diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/WalletReducer.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/WalletReducer.kt index fba952b703..bf3d1552a9 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/WalletReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/WalletReducer.kt @@ -6,7 +6,11 @@ import com.tangem.blockchain.common.Wallet import com.tangem.common.extensions.mapNotNullValues import com.tangem.domain.common.TwinCardNumber import com.tangem.tap.common.entities.FiatCurrency -import com.tangem.tap.common.extensions.* +import com.tangem.tap.common.extensions.toFiatRateString +import com.tangem.tap.common.extensions.toFiatString +import com.tangem.tap.common.extensions.toFiatValue +import com.tangem.tap.common.extensions.toFormattedCurrencyString +import com.tangem.tap.common.extensions.toFormattedFiatValue import com.tangem.tap.common.redux.AppState import com.tangem.tap.domain.TapError import com.tangem.tap.domain.extensions.getArtworkUrl @@ -14,7 +18,16 @@ import com.tangem.tap.domain.getFirstToken import com.tangem.tap.domain.tokens.models.BlockchainNetwork import com.tangem.tap.features.wallet.models.Currency import com.tangem.tap.features.wallet.models.WalletRent -import com.tangem.tap.features.wallet.redux.* +import com.tangem.tap.features.wallet.redux.AddressData +import com.tangem.tap.features.wallet.redux.Artwork +import com.tangem.tap.features.wallet.redux.ErrorType +import com.tangem.tap.features.wallet.redux.ProgressState +import com.tangem.tap.features.wallet.redux.WalletAction +import com.tangem.tap.features.wallet.redux.WalletAddresses +import com.tangem.tap.features.wallet.redux.WalletData +import com.tangem.tap.features.wallet.redux.WalletMainButton +import com.tangem.tap.features.wallet.redux.WalletState +import com.tangem.tap.features.wallet.redux.WalletStore import com.tangem.tap.features.wallet.ui.BalanceStatus import com.tangem.tap.features.wallet.ui.BalanceWidgetData import com.tangem.tap.store @@ -144,10 +157,6 @@ private fun internalReduce(action: Action, state: AppState): WalletState { currencySymbol = walletData.currencyData.currencySymbol, ), mainButton = WalletMainButton.SendButton(false), - tradeCryptoState = TradeCryptoState.from( - exchangeManager, - walletData - ) ) } ) @@ -171,13 +180,9 @@ private fun internalReduce(action: Action, state: AppState): WalletState { currencySymbol = wallet.currencyData.currencySymbol, ), mainButton = WalletMainButton.SendButton(false), - tradeCryptoState = TradeCryptoState.from(exchangeManager, wallet) ) } - val wallets = newState.updateTradeCryptoState( - exchangeManager, - newState.replaceSomeWallets(newWallets) - ) + val wallets = newState.replaceSomeWallets(newWallets) val walletStore = newState.getWalletStore(action.blockchain)?.updateWallets(wallets) newState = newState.updateWalletStore(walletStore) } @@ -210,14 +215,9 @@ private fun internalReduce(action: Action, state: AppState): WalletState { ) ) } - var updatedWalletStore = newState.getWalletStore(action.blockchain) + val updatedWalletStore = newState.getWalletStore(action.blockchain) ?.updateWallets(listOfNotNull(walletData)) - updatedWalletStore = - updatedWalletStore?.updateWallets( - newState.updateTradeCryptoState(exchangeManager, updatedWalletStore.walletsData) - ) - newState = newState.updateWalletStore(updatedWalletStore) } @@ -248,11 +248,7 @@ private fun internalReduce(action: Action, state: AppState): WalletState { ) ) } - val updatedWallets = - newState.updateTradeCryptoState( - exchangeManager, - walletStore!!.updateWallets(listOfNotNull(newWalletData) + tokenWallets).walletsData - ) + val updatedWallets = walletStore!!.updateWallets(listOfNotNull(newWalletData) + tokenWallets).walletsData newState = newState.updateWalletsData(updatedWallets) diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt index 0f54d5b13a..a84d052625 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt @@ -199,8 +199,8 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), } rowButtons.updateButtonsVisibility( - buyAllowed = selectedWallet.tradeCryptoState.isAvailableToBuy(), - sellAllowed = selectedWallet.tradeCryptoState.isAvailableToSell(), + buyAllowed = selectedWallet.isAvailableToBuy, + sellAllowed = selectedWallet.isAvailableToSell, sendAllowed = selectedWallet.mainButton.enabled, ) } diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/SingleWalletView.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/SingleWalletView.kt index fa046cc3f0..7f473f4b4d 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/SingleWalletView.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/SingleWalletView.kt @@ -117,11 +117,9 @@ class SingleWalletView : WalletView() { } private fun setupRowButtons(state: WalletData, rowButtons: WalletDetailsButtonsRow) { - val allowedToBuy = state.tradeCryptoState.isAvailableToBuy() - val allowedToSell = state.tradeCryptoState.isAvailableToSell() rowButtons.updateButtonsVisibility( - buyAllowed = allowedToBuy, - sellAllowed = allowedToSell, + buyAllowed = state.isAvailableToBuy, + sellAllowed = state.isAvailableToSell, sendAllowed = state.mainButton.enabled, ) diff --git a/app/src/main/java/com/tangem/tap/network/exchangeServices/CurrencyExchangeManager.kt b/app/src/main/java/com/tangem/tap/network/exchangeServices/CurrencyExchangeManager.kt index 39f201a9b1..85720c4306 100644 --- a/app/src/main/java/com/tangem/tap/network/exchangeServices/CurrencyExchangeManager.kt +++ b/app/src/main/java/com/tangem/tap/network/exchangeServices/CurrencyExchangeManager.kt @@ -74,6 +74,14 @@ class CurrencyExchangeManager( } enum class Action { Buy, Sell } + + companion object { + fun dummy(): CurrencyExchangeManager = CurrencyExchangeManager( + buyService = ExchangeService.dummy(), + sellService = ExchangeService.dummy(), + primaryRules = ExchangeRules.dummy(), + ) + } } suspend fun CurrencyExchangeManager.buyErc20TestnetTokens( diff --git a/app/src/main/java/com/tangem/tap/network/exchangeServices/ExchangeService.kt b/app/src/main/java/com/tangem/tap/network/exchangeServices/ExchangeService.kt index 34f37dddf9..f7db8b210f 100644 --- a/app/src/main/java/com/tangem/tap/network/exchangeServices/ExchangeService.kt +++ b/app/src/main/java/com/tangem/tap/network/exchangeServices/ExchangeService.kt @@ -5,6 +5,16 @@ import com.tangem.tap.features.wallet.models.Currency interface ExchangeService: ExchangeRules { suspend fun update() + + companion object { + fun dummy(): ExchangeService = object : ExchangeService { + override suspend fun update() {} + override fun isBuyAllowed(): Boolean = false + override fun isSellAllowed(): Boolean = false + override fun availableForBuy(currency: Currency): Boolean = false + override fun availableForSell(currency: Currency): Boolean = false + } + } } interface ExchangeRules { @@ -12,6 +22,15 @@ interface ExchangeRules { fun isSellAllowed(): Boolean fun availableForBuy(currency: Currency):Boolean fun availableForSell(currency: Currency):Boolean + + companion object { + fun dummy(): ExchangeRules = object : ExchangeRules { + override fun isBuyAllowed(): Boolean = false + override fun isSellAllowed(): Boolean = false + override fun availableForBuy(currency: Currency): Boolean = false + override fun availableForSell(currency: Currency): Boolean = false + } + } } interface ExchangeUrlBuilder {