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 c3092a3714..f03fc2cd20 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 @@ -9,11 +9,8 @@ import com.tangem.common.extensions.guard import com.tangem.core.analytics.Analytics import com.tangem.core.navigation.AppScreen import com.tangem.core.navigation.NavigationAction -import com.tangem.domain.common.extensions.toCoinId -import com.tangem.domain.common.extensions.toNetworkId import com.tangem.domain.tokens.legacy.TradeCryptoAction import com.tangem.domain.tokens.model.CryptoCurrency -import com.tangem.domain.tokens.model.Network import com.tangem.feature.swap.presentation.SwapFragment import com.tangem.features.send.api.navigation.SendRouter import com.tangem.tap.common.analytics.events.AnalyticsParam @@ -25,7 +22,6 @@ import com.tangem.tap.common.extensions.dispatchOnMain import com.tangem.tap.common.extensions.dispatchOpenUrl import com.tangem.tap.common.redux.AppState import com.tangem.tap.domain.TapError -import com.tangem.tap.domain.tokens.getIconUrl import com.tangem.tap.features.demo.DemoHelper import com.tangem.tap.features.home.RUSSIA_COUNTRY_CODE import com.tangem.tap.features.send.redux.PrepareSendScreen @@ -42,7 +38,6 @@ import com.tangem.tap.store import kotlinx.coroutines.launch import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json -import com.tangem.feature.swap.domain.models.domain.Currency as SwapCurrency @Suppress("LargeClass") class TradeCryptoMiddleware { @@ -57,17 +52,12 @@ class TradeCryptoMiddleware { is TradeCryptoAction.SendCrypto -> preconfigureAndOpenSendScreen(action) is TradeCryptoAction.FinishSelling -> openReceiptUrl(action.transactionId) is TradeCryptoAction.Swap -> { - openSwap( - currency = store.state.walletState.selectedWalletData?.currency?.toSwapCurrency(), - derivationPath = store.state.walletState.selectedWalletData?.currency?.derivationPath, - ) + // todo remove old flow } is TradeCryptoAction.New.Buy -> proceedNewBuyAction(state, action) is TradeCryptoAction.New.Sell -> proceedNewSellAction(action) is TradeCryptoAction.New.Swap -> openSwap( - currency = action.cryptoCurrency.toSwapCurrency(), - derivationPath = action.cryptoCurrency.network.derivationPath.value, - network = action.cryptoCurrency.network, + currency = action.cryptoCurrency, ) is TradeCryptoAction.New.SendToken -> handleNewSendToken(action = action) is TradeCryptoAction.New.SendCoin -> handleNewSendCoin(action = action) @@ -267,70 +257,14 @@ class TradeCryptoMiddleware { )?.let { store.dispatchOpenUrl(it) } } - private fun openSwap(currency: SwapCurrency?, derivationPath: String?, network: Network? = null) { + private fun openSwap(currency: CryptoCurrency) { val bundle = bundleOf( SwapFragment.CURRENCY_BUNDLE_KEY to Json.encodeToString(currency), - SwapFragment.DERIVATION_PATH to derivationPath, - SwapFragment.NETWORK to network, ) store.dispatchOnMain(NavigationAction.NavigateTo(screen = AppScreen.Swap, bundle = bundle)) } - private fun CryptoCurrency.toSwapCurrency(): SwapCurrency { - val blockchain = Blockchain.fromId(network.id.value) - - return when (this) { - is CryptoCurrency.Coin -> { - SwapCurrency.NativeToken( - id = blockchain.toCoinId(), - name = name, - symbol = symbol, - networkId = blockchain.toNetworkId(), - // no need to set logoUrl for blockchain cause - // error when form url with coinId, coinId of eth and arbitrum the same - logoUrl = "", - ) - } - is CryptoCurrency.Token -> { - SwapCurrency.NonNativeToken( - id = id.rawCurrencyId ?: "", - name = name, - symbol = symbol, - networkId = blockchain.toNetworkId(), - logoUrl = getIconUrl(id.rawCurrencyId ?: ""), - contractAddress = contractAddress, - decimalCount = decimals, - ) - } - } - } - - private fun Currency.toSwapCurrency(): SwapCurrency { - return when (this) { - is Currency.Blockchain -> { - SwapCurrency.NativeToken( - id = blockchain.toCoinId(), - name = this.currencyName, - symbol = this.currencySymbol, - networkId = this.blockchain.toNetworkId(), - // no need to set logoUrl for blockchain cause - // error when form url with coinId, coinId of eth and arbitrum the same - logoUrl = "", - ) - } - is Currency.Token -> SwapCurrency.NonNativeToken( - id = this.token.id ?: "", - name = this.currencyName, - symbol = this.currencySymbol, - networkId = this.blockchain.toNetworkId(), - logoUrl = getIconUrl(this.token.id ?: ""), - contractAddress = this.token.contractAddress, - decimalCount = decimals, - ) - } - } - private fun handleNewSendToken(action: TradeCryptoAction.New.SendToken) { val currency = action.tokenCurrency val blockchain = Blockchain.fromId(currency.network.id.value) diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractor.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractor.kt index 13d3c2d3f4..2757583249 100644 --- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractor.kt +++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractor.kt @@ -9,9 +9,9 @@ import java.math.BigDecimal interface SwapInteractor { - suspend fun getTokensDataState(currency: Currency): TokensDataStateExpress + suspend fun getTokensDataState(currency: CryptoCurrency): TokensDataStateExpress - fun initDerivationPathAndNetwork(derivationPath: String?, network: Network?) + fun initDerivationPathAndNetwork(derivationPath: String?, network: Network) /** * Init tokens to swap, load tokens list available to swap for given network diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt index 4d0bfd3e52..763847b303 100644 --- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt +++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt @@ -1,7 +1,7 @@ package com.tangem.feature.swap.domain -import com.tangem.domain.tokens.AddCryptoCurrenciesUseCase import arrow.core.getOrElse +import com.tangem.domain.tokens.AddCryptoCurrenciesUseCase import com.tangem.domain.tokens.GetCryptoCurrencyStatusUseCase import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.domain.tokens.model.CryptoCurrencyStatus @@ -52,7 +52,7 @@ internal class SwapInteractorImpl @Inject constructor( private var derivationPath: String? = null private var network: Network? = null - override suspend fun getTokensDataState(currency: Currency): TokensDataStateExpress { + override suspend fun getTokensDataState(currency: CryptoCurrency): TokensDataStateExpress { val selectedWallet = getSelectedWalletSyncUseCase().fold( ifLeft = { null }, ifRight = { it }, @@ -65,36 +65,32 @@ internal class SwapInteractorImpl @Inject constructor( .getOrElse { emptyList() } val walletCurrencyStatusesExceptInitial = walletCurrencyStatuses.filter { - it.currency.network.backendId != currency.networkId || + it.currency.network.backendId != currency.network.backendId || it.currency.getContractAddress() != currency.getContractAddress() } val pairsLeast = getPairs( initialCurrency = LeastTokenInfo( - contractAddress = (currency as? Currency.NonNativeToken)?.contractAddress ?: "0", - network = currency.networkId, + contractAddress = (currency as? CryptoCurrency.Token)?.contractAddress ?: "0", + network = currency.network.backendId, ), currenciesList = walletCurrencyStatusesExceptInitial.map { it.currency }, ) - val initialCryptoCurrency = mapLegacyCurrencyToCryptoCurrency(currency, walletCurrencyStatuses) - ?: error("Initial crypto currency must not be null") - return TokensDataStateExpress( - initialCryptoCurrency = initialCryptoCurrency, fromGroup = getToCurrenciesGroup( - currency = initialCryptoCurrency, + currency = currency, leastPairs = pairsLeast, cryptoCurrenciesList = walletCurrencyStatusesExceptInitial, tokenInfoForFilter = { it.from }, - tokenInfoForAvailable = { it.to } + tokenInfoForAvailable = { it.to }, ), toGroup = getToCurrenciesGroup( - currency = initialCryptoCurrency, + currency = currency, leastPairs = pairsLeast, cryptoCurrenciesList = walletCurrencyStatusesExceptInitial, tokenInfoForFilter = { it.to }, - tokenInfoForAvailable = { it.from } + tokenInfoForAvailable = { it.from }, ), ) } @@ -107,8 +103,8 @@ internal class SwapInteractorImpl @Inject constructor( tokenInfoForAvailable: (SwapPairLeast) -> LeastTokenInfo, ): CurrenciesGroup { val filteredPairs = leastPairs.filter { - tokenInfoForFilter(it).contractAddress == currency.getContractAddress() - && tokenInfoForFilter(it).network == currency.network.backendId + tokenInfoForFilter(it).contractAddress == currency.getContractAddress() && + tokenInfoForFilter(it).network == currency.network.backendId } val availableCryptoCurrencies = filteredPairs.mapNotNull { pair -> @@ -125,17 +121,6 @@ internal class SwapInteractorImpl @Inject constructor( ) } - private fun mapLegacyCurrencyToCryptoCurrency( - currency: Currency, - currencies: List, - ): CryptoCurrency? { - return currencies.map { it.currency } - .find { - it.network.backendId == currency.networkId && - it.getContractAddress() == currency.getContractAddress() - } - } - private fun findCryptoCurrencyStatusByLeastInfo( leastTokenInfo: LeastTokenInfo, cryptoCurrencyStatusesList: List, @@ -165,7 +150,7 @@ internal class SwapInteractorImpl @Inject constructor( } @Deprecated("used in old swap mechanism") - override fun initDerivationPathAndNetwork(derivationPath: String?, network: Network?) { + override fun initDerivationPathAndNetwork(derivationPath: String?, network: Network) { this.derivationPath = derivationPath this.network = network } diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/ui/TokensDataStateExpress.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/ui/TokensDataStateExpress.kt index 8beb9ed216..752e9184a7 100644 --- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/ui/TokensDataStateExpress.kt +++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/ui/TokensDataStateExpress.kt @@ -4,7 +4,6 @@ import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.feature.swap.domain.models.domain.CryptoCurrencySwapInfo data class TokensDataStateExpress( - val initialCryptoCurrency: CryptoCurrency, val fromGroup: CurrenciesGroup, val toGroup: CurrenciesGroup, ) diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/presentation/SwapFragment.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/presentation/SwapFragment.kt index 8562c1e5db..00744ef60a 100644 --- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/presentation/SwapFragment.kt +++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/presentation/SwapFragment.kt @@ -82,7 +82,5 @@ class SwapFragment : ComposeFragment() { companion object { const val CURRENCY_BUNDLE_KEY = "swap_currency" - const val DERIVATION_PATH = "DERIVATION_STYLE" - const val NETWORK = "NETWORK" } } \ No newline at end of file diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/StateBuilder.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/StateBuilder.kt index 0fc01468a0..bea53175af 100644 --- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/StateBuilder.kt +++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/StateBuilder.kt @@ -12,9 +12,7 @@ import com.tangem.core.ui.extensions.wrappedList import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.feature.swap.converters.TokensDataConverter import com.tangem.feature.swap.domain.models.DataError -import com.tangem.feature.swap.domain.models.domain.Currency import com.tangem.feature.swap.domain.models.domain.NetworkInfo -import com.tangem.feature.swap.domain.models.domain.isNonNative import com.tangem.feature.swap.domain.models.formatToUIRepresentation import com.tangem.feature.swap.domain.models.ui.* import com.tangem.feature.swap.models.* @@ -34,19 +32,19 @@ internal class StateBuilder(val actions: UiActions, val isBalanceHiddenProvider: isBalanceHiddenProvider = isBalanceHiddenProvider, ) - fun createInitialLoadingState(initialCurrency: Currency, networkInfo: NetworkInfo): SwapStateHolder { + fun createInitialLoadingState(initialCurrency: CryptoCurrency, networkInfo: NetworkInfo): SwapStateHolder { return SwapStateHolder( - networkId = initialCurrency.networkId, + networkId = initialCurrency.network.backendId, blockchainId = networkInfo.blockchainId, sendCardData = SwapCardData( type = TransactionCardType.SendCard(actions.onAmountChanged, actions.onAmountSelected), amountEquivalent = null, amountTextFieldValue = null, - tokenIconUrl = initialCurrency.logoUrl, + tokenIconUrl = initialCurrency.iconUrl, tokenCurrency = initialCurrency.symbol, - coinId = initialCurrency.id, + coinId = null, canSelectAnotherToken = false, - isNotNativeToken = initialCurrency.isNonNative(), + isNotNativeToken = initialCurrency is CryptoCurrency.Token, balance = "", isBalanceHidden = true, ), diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/viewmodels/SwapViewModel.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/viewmodels/SwapViewModel.kt index 7ba34b693d..d4dc926f85 100644 --- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/viewmodels/SwapViewModel.kt +++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/viewmodels/SwapViewModel.kt @@ -9,11 +9,9 @@ import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.core.ui.utils.InputNumberFormatter import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase import com.tangem.domain.tokens.model.CryptoCurrency -import com.tangem.domain.tokens.model.Network import com.tangem.feature.swap.analytics.SwapEvents import com.tangem.feature.swap.domain.BlockchainInteractor import com.tangem.feature.swap.domain.SwapInteractor -import com.tangem.feature.swap.domain.models.domain.Currency import com.tangem.feature.swap.domain.models.domain.PermissionOptions import com.tangem.feature.swap.domain.models.formatToUIRepresentation import com.tangem.feature.swap.domain.models.ui.* @@ -52,17 +50,11 @@ internal class SwapViewModel @Inject constructor( savedStateHandle: SavedStateHandle, ) : ViewModel(), DefaultLifecycleObserver { - // try to get rid of this and use only CryptoCurrency - private val currency = Json.decodeFromString( + private val initialCryptoCurrency = Json.decodeFromString( savedStateHandle[SwapFragment.CURRENCY_BUNDLE_KEY] ?: error("no expected parameter Currency found"), ) - private var cryptoCurrency: CryptoCurrency by Delegates.notNull() - - private val derivationPath = savedStateHandle.get(SwapFragment.DERIVATION_PATH) - private val network = savedStateHandle.get(SwapFragment.NETWORK) - private var isBalanceHidden = true private val stateBuilder = StateBuilder( @@ -75,12 +67,12 @@ internal class SwapViewModel @Inject constructor( private val amountDebouncer = Debouncer() private val singleTaskScheduler = SingleTaskScheduler() - private var dataState by mutableStateOf(SwapProcessDataState(networkId = currency.networkId)) + private var dataState by mutableStateOf(SwapProcessDataState(networkId = initialCryptoCurrency.network.backendId)) var uiState: SwapStateHolder by mutableStateOf( stateBuilder.createInitialLoadingState( - initialCurrency = currency, - networkInfo = blockchainInteractor.getBlockchainInfo(currency.networkId), + initialCurrency = initialCryptoCurrency, + networkInfo = blockchainInteractor.getBlockchainInfo(initialCryptoCurrency.network.backendId), ), ) private set @@ -93,8 +85,11 @@ internal class SwapViewModel @Inject constructor( get() = swapRouter.currentScreen init { - swapInteractor.initDerivationPathAndNetwork(derivationPath, network) - initTokens(currency) + swapInteractor.initDerivationPathAndNetwork( + derivationPath = initialCryptoCurrency.network.derivationPath.value, + network = initialCryptoCurrency.network, + ) + initTokens(initialCryptoCurrency) } override fun onCreate(owner: LifecycleOwner) { @@ -115,7 +110,7 @@ internal class SwapViewModel @Inject constructor( } fun onScreenOpened() { - analyticsEventHandler.send(SwapEvents.SwapScreenOpened(currency.symbol)) + analyticsEventHandler.send(SwapEvents.SwapScreenOpened(initialCryptoCurrency.symbol)) } fun setRouter(router: SwapRouter) { @@ -133,21 +128,20 @@ internal class SwapViewModel @Inject constructor( } @Suppress("UnusedPrivateMember") - private fun initTokens(currency: Currency) { + private fun initTokens(currency: CryptoCurrency) { // new flow viewModelScope.launch(dispatchers.main) { runCatching(dispatchers.io) { - swapInteractor.getTokensDataState(currency) + swapInteractor.getTokensDataState(initialCryptoCurrency) }.onSuccess { state -> dataState = dataState.copy( - fromCryptoCurrency = state.initialCryptoCurrency, + fromCryptoCurrency = initialCryptoCurrency, toCryptoCurrency = state.toGroup.available.first().currencyStatus.currency ) - cryptoCurrency = state.initialCryptoCurrency // updateTokensState(dataState = state.foundTokensState) startLoadingQuotes( - fromToken = state.initialCryptoCurrency, + fromToken = initialCryptoCurrency, toToken = state.toGroup.available.first().currencyStatus.currency, amount = lastAmount.value, ) @@ -157,39 +151,39 @@ internal class SwapViewModel @Inject constructor( } // old flow - viewModelScope.launch(dispatchers.main) { - runCatching(dispatchers.io) { - swapInteractor.initTokensToSwap(currency) - } - .onSuccess { state -> - // dataState = dataState.copy( - // fromCurrency = state.preselectTokens.fromToken, - // toCurrency = state.preselectTokens.toToken, - // ) - // updateTokensState(dataState = state.foundTokensState) - // startLoadingQuotes( - // fromToken = state.preselectTokens.fromToken, - // toToken = state.preselectTokens.toToken, - // amount = lastAmount.value, - // ) - } - .onFailure { - Timber.tag(loggingTag).e(it) - } - } + // viewModelScope.launch(dispatchers.main) { + // runCatching(dispatchers.io) { + // swapInteractor.initTokensToSwap(currency) + // } + // .onSuccess { state -> + // // dataState = dataState.copy( + // // fromCurrency = state.preselectTokens.fromToken, + // // toCurrency = state.preselectTokens.toToken, + // // ) + // // updateTokensState(dataState = state.foundTokensState) + // // startLoadingQuotes( + // // fromToken = state.preselectTokens.fromToken, + // // toToken = state.preselectTokens.toToken, + // // amount = lastAmount.value, + // // ) + // } + // .onFailure { + // Timber.tag(loggingTag).e(it) + // } + // } } private fun updateTokensState(dataState: FoundTokensStateExpress) { uiState = stateBuilder.addTokensToState( uiState = uiState, dataState = dataState, - networkInfo = blockchainInteractor.getBlockchainInfo(currency.networkId), + networkInfo = blockchainInteractor.getBlockchainInfo(initialCryptoCurrency.network.backendId), ) } private fun startLoadingQuotes(fromToken: CryptoCurrency, toToken: CryptoCurrency, amount: String) { singleTaskScheduler.cancelTask() - uiState = stateBuilder.createQuotesLoadingState(uiState, fromToken, toToken, cryptoCurrency.id.value) + uiState = stateBuilder.createQuotesLoadingState(uiState, fromToken, toToken, initialCryptoCurrency.id.value) singleTaskScheduler.scheduleTask( viewModelScope, loadQuotesTask( @@ -395,9 +389,9 @@ internal class SwapViewModel @Inject constructor( val toToken: CryptoCurrency if (isOrderReversed) { fromToken = foundToken - toToken = cryptoCurrency + toToken = initialCryptoCurrency } else { - fromToken = cryptoCurrency + fromToken = initialCryptoCurrency toToken = foundToken } dataState = dataState.copy( @@ -445,7 +439,7 @@ internal class SwapViewModel @Inject constructor( private fun onMaxAmountClicked() { dataState.fromCryptoCurrency?.let { - val balance = swapInteractor.getTokenBalance(cryptoCurrency.network.id.value, it) + val balance = swapInteractor.getTokenBalance(initialCryptoCurrency.network.id.value, it) onAmountChanged(balance.formatToUIRepresentation()) } }