diff --git a/core/ui/src/main/res/drawable/ic_no_token_44.xml b/core/ui/src/main/res/drawable/ic_no_token_44.xml
new file mode 100644
index 0000000000..49e3b75b2a
--- /dev/null
+++ b/core/ui/src/main/res/drawable/ic_no_token_44.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultQuotesRepository.kt b/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultQuotesRepository.kt
index cdd04c62ce..7aa81fc78c 100644
--- a/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultQuotesRepository.kt
+++ b/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultQuotesRepository.kt
@@ -67,6 +67,14 @@ internal class DefaultQuotesRepository(
}
}
+ override suspend fun getQuoteSync(currencyId: CryptoCurrency.ID): Quote {
+ return withContext(dispatchers.io) {
+ val quote = quotesStore.getSync(setOf(currencyId)).firstOrNull()
+ requireNotNull(quote) { "Unable to get quote for $currencyId" }
+ quotesConverter.convert(quote)
+ }
+ }
+
private suspend fun fetchExpiredQuotes(
currenciesIds: Set,
appCurrencyId: String,
diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCryptoCurrencyStatusSyncUseCase.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCryptoCurrencyStatusSyncUseCase.kt
new file mode 100644
index 0000000000..ffe6e79c3b
--- /dev/null
+++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCryptoCurrencyStatusSyncUseCase.kt
@@ -0,0 +1,36 @@
+package com.tangem.domain.tokens
+
+import arrow.core.Either
+import com.tangem.domain.tokens.error.TokenListError
+import com.tangem.domain.tokens.error.mapper.mapToTokenListError
+import com.tangem.domain.tokens.model.CryptoCurrency
+import com.tangem.domain.tokens.model.CryptoCurrencyStatus
+import com.tangem.domain.tokens.operations.CurrenciesStatusesOperations
+import com.tangem.domain.tokens.repository.CurrenciesRepository
+import com.tangem.domain.tokens.repository.NetworksRepository
+import com.tangem.domain.tokens.repository.QuotesRepository
+import com.tangem.domain.wallets.models.UserWalletId
+import com.tangem.utils.coroutines.CoroutineDispatcherProvider
+
+class GetCryptoCurrencyStatusSyncUseCase(
+ internal val currenciesRepository: CurrenciesRepository,
+ internal val quotesRepository: QuotesRepository,
+ internal val networksRepository: NetworksRepository,
+ internal val dispatchers: CoroutineDispatcherProvider,
+) {
+
+ suspend operator fun invoke(
+ userWalletId: UserWalletId,
+ cryptoCurrencyId: CryptoCurrency.ID,
+ ): Either {
+ val operations = CurrenciesStatusesOperations(
+ userWalletId = userWalletId,
+ currenciesRepository = currenciesRepository,
+ quotesRepository = quotesRepository,
+ networksRepository = networksRepository,
+ )
+
+ return operations.getCurrencyStatusSync(cryptoCurrencyId)
+ .mapLeft { error -> error.mapToTokenListError() }
+ }
+}
\ No newline at end of file
diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CurrenciesStatusesOperations.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CurrenciesStatusesOperations.kt
index 3ce6112296..a86698763b 100644
--- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CurrenciesStatusesOperations.kt
+++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CurrenciesStatusesOperations.kt
@@ -85,6 +85,28 @@ internal class CurrenciesStatusesOperations(
}
}
+ suspend fun getCurrencyStatusSync(cryptoCurrencyId: CryptoCurrency.ID): Either {
+ return either {
+ catch(
+ block = {
+ val currency =
+ currenciesRepository.getMultiCurrencyWalletCurrency(userWalletId, cryptoCurrencyId)
+ val quotes = quotesRepository.getQuoteSync(cryptoCurrencyId).right()
+ val networkStatuses =
+ networksRepository.getNetworkStatusesSync(
+ userWalletId,
+ setOf(currency.network),
+ false,
+ ).firstOrNull {
+ it.network == currency.network
+ }.right()
+ return createCurrencyStatus(currency, quotes, networkStatuses)
+ },
+ catch = { raise(Error.DataError(it)) },
+ )
+ }
+ }
+
fun getCardCurrenciesStatusesFlow(): Flow>> {
return flow {
val nonEmptyCurrencies = recover(
diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/QuotesRepository.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/QuotesRepository.kt
index a44b1e6c99..4c38eda580 100644
--- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/QuotesRepository.kt
+++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/QuotesRepository.kt
@@ -29,4 +29,6 @@ interface QuotesRepository {
* @return A [Flow] emitting a set of quotes corresponding to the specified cryptocurrencies.
*/
suspend fun getQuotesSync(currenciesIds: Set, refresh: Boolean): Set
+
+ suspend fun getQuoteSync(currencyId: CryptoCurrency.ID): Quote
}
\ No newline at end of file
diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/BlockchainInteractor.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/BlockchainInteractor.kt
index 229911c654..8883e0f1a3 100644
--- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/BlockchainInteractor.kt
+++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/BlockchainInteractor.kt
@@ -1,12 +1,9 @@
package com.tangem.feature.swap.domain
-import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.feature.swap.domain.models.domain.NetworkInfo
interface BlockchainInteractor {
- fun getTokenDecimals(token: CryptoCurrency): Int
-
/**
* In app blockchain id, actual in blockchain sdk, not the same as networkId
*
diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/DefaultBlockchainInteractor.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/DefaultBlockchainInteractor.kt
index cb99b58076..836f193fe3 100644
--- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/DefaultBlockchainInteractor.kt
+++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/DefaultBlockchainInteractor.kt
@@ -1,6 +1,5 @@
package com.tangem.feature.swap.domain
-import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.feature.swap.domain.models.domain.NetworkInfo
import com.tangem.lib.crypto.TransactionManager
import javax.inject.Inject
@@ -22,12 +21,4 @@ internal class DefaultBlockchainInteractor @Inject constructor(
override fun getExplorerTransactionLink(networkId: String, txAddress: String): String {
return transactionManager.getExplorerTransactionLink(networkId, txAddress)
}
-
- override fun getTokenDecimals(token: CryptoCurrency): Int {
- return if (token is CryptoCurrency.Token) {
- token.decimals
- } else {
- transactionManager.getNativeTokenDecimals(token.network.backendId)
- }
- }
}
\ No newline at end of file
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 2757583249..073c2464d8 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
@@ -2,6 +2,7 @@ package com.tangem.feature.swap.domain
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.tokens.model.Network
+import com.tangem.domain.wallets.models.UserWallet
import com.tangem.feature.swap.domain.models.SwapAmount
import com.tangem.feature.swap.domain.models.domain.*
import com.tangem.feature.swap.domain.models.ui.*
@@ -110,4 +111,6 @@ interface SwapInteractor {
networkId: String,
fromToken: CryptoCurrency,
): Boolean
+
+ fun getSelectedWallet(): UserWallet?
}
\ No newline at end of file
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 ec089f6df7..1cfcebfb20 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
@@ -8,6 +8,7 @@ import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.tokens.model.Network
import com.tangem.domain.tokens.repository.CurrenciesRepository
import com.tangem.domain.tokens.repository.NetworksRepository
+import com.tangem.domain.wallets.models.UserWallet
import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase
import com.tangem.feature.swap.domain.cache.SwapDataCache
import com.tangem.feature.swap.domain.converters.SwapCurrencyConverter
@@ -93,6 +94,10 @@ internal class SwapInteractorImpl @Inject constructor(
)
}
+ override fun getSelectedWallet(): UserWallet? {
+ return getSelectedWalletSyncUseCase().getOrNull()
+ }
+
private fun getToCurrenciesGroup(
currency: CryptoCurrency,
leastPairs: List,
diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/di/SwapDomainModule.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/di/SwapDomainModule.kt
index 7fa93f1c70..8845c68949 100644
--- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/di/SwapDomainModule.kt
+++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/di/SwapDomainModule.kt
@@ -1,7 +1,6 @@
package com.tangem.feature.swap.domain.di
import com.tangem.domain.tokens.GetCardTokensListUseCase
-import com.tangem.domain.tokens.GetCryptoCurrenciesUseCase
import com.tangem.domain.tokens.GetCryptoCurrencyStatusesSyncUseCase
import com.tangem.domain.tokens.repository.CurrenciesRepository
import com.tangem.domain.tokens.repository.NetworksRepository
@@ -66,13 +65,6 @@ class SwapDomainModule {
return GetSelectedWalletSyncUseCase(walletsStateHolder = walletsStateHolder)
}
- @SwapScope
- @Provides
- @Singleton
- fun providesGetCryptoCurrenciesUseCase(currenciesRepository: CurrenciesRepository): GetCryptoCurrenciesUseCase {
- return GetCryptoCurrenciesUseCase(currenciesRepository = currenciesRepository)
- }
-
@SwapScope
@Provides
@Singleton
diff --git a/features/swap/presentation/build.gradle.kts b/features/swap/presentation/build.gradle.kts
index 8be06eaf61..86879ce609 100644
--- a/features/swap/presentation/build.gradle.kts
+++ b/features/swap/presentation/build.gradle.kts
@@ -21,6 +21,10 @@ dependencies {
implementation(projects.domain.appCurrency.models)
implementation(projects.domain.balanceHiding)
implementation(projects.domain.balanceHiding.models)
+ implementation(projects.domain.tokens)
+ implementation(projects.domain.tokens.models)
+ implementation(projects.domain.wallets)
+ implementation(projects.domain.wallets.models)
/** AndroidX */
implementation(deps.androidx.activity.compose)
diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/converters/TokensDataConverter.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/converters/TokensDataConverter.kt
index e3eff35d4c..6f42bbd1d2 100644
--- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/converters/TokensDataConverter.kt
+++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/converters/TokensDataConverter.kt
@@ -32,13 +32,17 @@ class TokensDataConverter(
availableTokens = value.available.map { tokenWithBalanceToTokenToSelect(it, true) }
.toMutableList()
.apply {
- this.add(0, availableTitle)
+ if (this.isNotEmpty()) {
+ this.add(0, availableTitle)
+ }
}
.toImmutableList(),
unavailableTokens = value.unavailable.map { tokenWithBalanceToTokenToSelect(it, false) }
.toMutableList()
.apply {
- this.add(0, unavailableTitle)
+ if (this.isNotEmpty()) {
+ this.add(0, unavailableTitle)
+ }
}
.toImmutableList(),
onSearchEntered = onSearchEntered,
diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/di/SwapPresentationModule.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/di/SwapPresentationModule.kt
new file mode 100644
index 0000000000..441abf4a2e
--- /dev/null
+++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/di/SwapPresentationModule.kt
@@ -0,0 +1,34 @@
+package com.tangem.feature.swap.di
+
+import com.tangem.domain.tokens.GetCryptoCurrencyStatusSyncUseCase
+import com.tangem.domain.tokens.repository.CurrenciesRepository
+import com.tangem.domain.tokens.repository.NetworksRepository
+import com.tangem.domain.tokens.repository.QuotesRepository
+import com.tangem.feature.swap.domain.*
+import com.tangem.utils.coroutines.CoroutineDispatcherProvider
+import dagger.Module
+import dagger.Provides
+import dagger.hilt.InstallIn
+import dagger.hilt.android.components.ViewModelComponent
+import dagger.hilt.android.scopes.ViewModelScoped
+
+@Module
+@InstallIn(ViewModelComponent::class)
+class SwapPresentationModule {
+
+ @ViewModelScoped
+ @Provides
+ fun providesGetCryptoCurrenciesUseCase(
+ currenciesRepository: CurrenciesRepository,
+ dispatcherProvider: CoroutineDispatcherProvider,
+ quotesRepository: QuotesRepository,
+ networksRepository: NetworksRepository,
+ ): GetCryptoCurrencyStatusSyncUseCase {
+ return GetCryptoCurrencyStatusSyncUseCase(
+ currenciesRepository = currenciesRepository,
+ quotesRepository = quotesRepository,
+ networksRepository = networksRepository,
+ dispatchers = dispatcherProvider,
+ )
+ }
+}
\ No newline at end of file
diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/models/SwapStateHolder.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/models/SwapStateHolder.kt
index ace9ee54d5..6427891e34 100644
--- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/models/SwapStateHolder.kt
+++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/models/SwapStateHolder.kt
@@ -7,8 +7,8 @@ import com.tangem.core.ui.components.states.SelectableItemsState
import com.tangem.feature.swap.domain.models.ui.TxFee
data class SwapStateHolder(
- val sendCardData: SwapCardData,
- val receiveCardData: SwapCardData,
+ val sendCardData: SwapCardState,
+ val receiveCardData: SwapCardState,
val networkCurrency: String,
val networkId: String,
val blockchainId: String, // not the same as networkId, its local id in app
@@ -33,18 +33,28 @@ data class SwapStateHolder(
val onCancelPermissionBottomSheet: () -> Unit = {},
)
-data class SwapCardData(
- val type: TransactionCardType,
- val amountEquivalent: String?,
- val coinId: String?,
- val amountTextFieldValue: TextFieldValue?,
- val tokenIconUrl: String?,
- val tokenCurrency: String,
- val balance: String,
- val isBalanceHidden: Boolean,
- val isNotNativeToken: Boolean,
- val canSelectAnotherToken: Boolean = false,
-)
+sealed class SwapCardState {
+
+ data class SwapCardData(
+ val type: TransactionCardType,
+ val amountEquivalent: String?,
+ val coinId: String?,
+ val amountTextFieldValue: TextFieldValue?,
+ val tokenIconUrl: String?,
+ val tokenCurrency: String,
+ val balance: String,
+ val isBalanceHidden: Boolean,
+ val isNotNativeToken: Boolean,
+ val canSelectAnotherToken: Boolean = false,
+ ) : SwapCardState()
+
+ data class Empty(
+ val type: TransactionCardType,
+ val amountEquivalent: String?,
+ val amountTextFieldValue: TextFieldValue?,
+ val canSelectAnotherToken: Boolean = false,
+ ) : SwapCardState()
+}
data class SwapButton(
val enabled: Boolean,
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 510502e088..2b1c60f67a 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
@@ -8,9 +8,12 @@ import com.tangem.core.ui.components.states.Item
import com.tangem.core.ui.components.states.SelectableItemsState
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resourceReference
+import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.extensions.wrappedList
+import com.tangem.core.ui.utils.BigDecimalFormatter
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.tokens.model.CryptoCurrency
+import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.feature.swap.converters.TokensDataConverter
import com.tangem.feature.swap.domain.models.DataError
import com.tangem.feature.swap.domain.models.domain.NetworkInfo
@@ -28,7 +31,7 @@ import kotlinx.collections.immutable.toImmutableList
internal class StateBuilder(
private val actions: UiActions,
private val isBalanceHiddenProvider: Provider,
- appCurrencyProvider: Provider,
+ private val appCurrencyProvider: Provider,
) {
private val tokensDataConverter = TokensDataConverter(
@@ -42,7 +45,7 @@ internal class StateBuilder(
return SwapStateHolder(
networkId = initialCurrency.network.backendId,
blockchainId = networkInfo.blockchainId,
- sendCardData = SwapCardData(
+ sendCardData = SwapCardState.SwapCardData(
type = TransactionCardType.SendCard(actions.onAmountChanged, actions.onAmountSelected),
amountEquivalent = null,
amountTextFieldValue = null,
@@ -54,7 +57,7 @@ internal class StateBuilder(
balance = "",
isBalanceHidden = true,
),
- receiveCardData = SwapCardData(
+ receiveCardData = SwapCardState.SwapCardData(
type = TransactionCardType.ReceiveCard(),
amountEquivalent = null,
tokenIconUrl = "",
@@ -79,6 +82,53 @@ internal class StateBuilder(
)
}
+ fun createNoAvailableTokensToSwapState(
+ uiStateHolder: SwapStateHolder,
+ fromToken: CryptoCurrencyStatus,
+ ): SwapStateHolder {
+ if (uiStateHolder.sendCardData !is SwapCardState.SwapCardData) return uiStateHolder
+ return uiStateHolder.copy(
+ sendCardData = SwapCardState.SwapCardData(
+ type = requireNotNull(uiStateHolder.sendCardData.type as? TransactionCardType.SendCard),
+ amountTextFieldValue = TextFieldValue(
+ text = "0",
+ ),
+ amountEquivalent = "0 ${appCurrencyProvider.invoke().symbol}",
+ tokenIconUrl = uiStateHolder.sendCardData.tokenIconUrl,
+ coinId = uiStateHolder.sendCardData.coinId,
+ isNotNativeToken = uiStateHolder.sendCardData.isNotNativeToken,
+ tokenCurrency = uiStateHolder.sendCardData.tokenCurrency,
+ canSelectAnotherToken = uiStateHolder.sendCardData.canSelectAnotherToken,
+ balance = fromToken.getFormattedAmount(),
+ isBalanceHidden = isBalanceHiddenProvider(),
+ ),
+ receiveCardData = SwapCardState.Empty(
+ type = TransactionCardType.ReceiveCard(),
+ amountEquivalent = "0 ${appCurrencyProvider.invoke().symbol}",
+ amountTextFieldValue = TextFieldValue(
+ text = "0",
+ ),
+ canSelectAnotherToken = true,
+ ),
+ warnings = listOf(
+ SwapWarning.NoAvailableTokensToSwap(
+ notificationConfig = NotificationConfig(
+ title = stringReference("No tokens"),
+ subtitle = stringReference("Swap tokens not available"),
+ iconResId = R.drawable.ic_alert_24,
+ ),
+ ),
+ ),
+ fee = FeeState.Empty,
+ swapButton = SwapButton(
+ enabled = false,
+ loading = false,
+ onClick = { },
+ ),
+ updateInProgress = false,
+ )
+ }
+
fun createQuotesLoadingState(
uiStateHolder: SwapStateHolder,
fromToken: CryptoCurrency,
@@ -87,8 +137,10 @@ internal class StateBuilder(
): SwapStateHolder {
val canSelectSendToken = mainTokenId != fromToken.id.value // TODO look at id matching
val canSelectReceiveToken = mainTokenId != toToken.id.value // TODO look at id matching
+ if (uiStateHolder.sendCardData !is SwapCardState.SwapCardData) return uiStateHolder
+ if (uiStateHolder.receiveCardData !is SwapCardState.SwapCardData) return uiStateHolder
return uiStateHolder.copy(
- sendCardData = SwapCardData(
+ sendCardData = SwapCardState.SwapCardData(
type = requireNotNull(uiStateHolder.sendCardData.type as? TransactionCardType.SendCard),
amountTextFieldValue = uiStateHolder.sendCardData.amountTextFieldValue,
amountEquivalent = null,
@@ -100,7 +152,7 @@ internal class StateBuilder(
balance = if (!canSelectSendToken) uiStateHolder.sendCardData.balance else "",
isBalanceHidden = isBalanceHiddenProvider(),
),
- receiveCardData = SwapCardData(
+ receiveCardData = SwapCardState.SwapCardData(
type = TransactionCardType.ReceiveCard(),
amountTextFieldValue = null,
amountEquivalent = null,
@@ -128,12 +180,15 @@ internal class StateBuilder(
* @param onFeeSetup callback for reset fee after auto update
* @return updated whole screen state
*/
+ @Suppress("LongMethod")
fun createQuotesLoadedState(
uiStateHolder: SwapStateHolder,
quoteModel: SwapState.QuotesLoadedState,
fromToken: CryptoCurrency,
onFeeSetup: (TxFee) -> Unit,
): SwapStateHolder {
+ if (uiStateHolder.sendCardData !is SwapCardState.SwapCardData) return uiStateHolder
+ if (uiStateHolder.receiveCardData !is SwapCardState.SwapCardData) return uiStateHolder
val warnings = mutableListOf()
if (!quoteModel.preparedSwapConfigState.isAllowedToSpend &&
quoteModel.preparedSwapConfigState.isFeeEnough &&
@@ -159,7 +214,7 @@ internal class StateBuilder(
}
val feeState = createFeeState(quoteModel, uiStateHolder, onFeeSetup)
return uiStateHolder.copy(
- sendCardData = SwapCardData(
+ sendCardData = SwapCardState.SwapCardData(
type = requireNotNull(uiStateHolder.sendCardData.type as? TransactionCardType.SendCard),
amountTextFieldValue = uiStateHolder.sendCardData.amountTextFieldValue,
amountEquivalent = quoteModel.fromTokenInfo.tokenFiatBalance,
@@ -171,7 +226,7 @@ internal class StateBuilder(
balance = quoteModel.fromTokenInfo.tokenWalletBalance,
isBalanceHidden = isBalanceHiddenProvider(),
),
- receiveCardData = SwapCardData(
+ receiveCardData = SwapCardState.SwapCardData(
type = TransactionCardType.ReceiveCard(),
amountTextFieldValue = TextFieldValue(quoteModel.toTokenInfo.tokenAmount.formatToUIRepresentation()),
amountEquivalent = quoteModel.toTokenInfo.tokenFiatBalance,
@@ -208,8 +263,10 @@ internal class StateBuilder(
uiStateHolder: SwapStateHolder,
emptyAmountState: SwapState.EmptyAmountState,
): SwapStateHolder {
+ if (uiStateHolder.sendCardData !is SwapCardState.SwapCardData) return uiStateHolder
+ if (uiStateHolder.receiveCardData !is SwapCardState.SwapCardData) return uiStateHolder
return uiStateHolder.copy(
- sendCardData = SwapCardData(
+ sendCardData = SwapCardState.SwapCardData(
type = requireNotNull(uiStateHolder.sendCardData.type as? TransactionCardType.SendCard),
amountTextFieldValue = uiStateHolder.sendCardData.amountTextFieldValue,
amountEquivalent = emptyAmountState.zeroAmountEquivalent,
@@ -221,7 +278,7 @@ internal class StateBuilder(
balance = emptyAmountState.fromTokenWalletBalance,
isBalanceHidden = isBalanceHiddenProvider(),
),
- receiveCardData = SwapCardData(
+ receiveCardData = SwapCardState.SwapCardData(
type = TransactionCardType.ReceiveCard(),
amountTextFieldValue = TextFieldValue("0"),
amountEquivalent = emptyAmountState.zeroAmountEquivalent,
@@ -268,6 +325,7 @@ internal class StateBuilder(
}
fun updateSwapAmount(uiState: SwapStateHolder, amount: String): SwapStateHolder {
+ if (uiState.sendCardData !is SwapCardState.SwapCardData) return uiState
return uiState.copy(
sendCardData = uiState.sendCardData.copy(
amountTextFieldValue = TextFieldValue(
@@ -279,6 +337,8 @@ internal class StateBuilder(
}
fun updateBalanceHiddenState(uiState: SwapStateHolder, isBalanceHidden: Boolean): SwapStateHolder {
+ if (uiState.sendCardData !is SwapCardState.SwapCardData) return uiState
+ if (uiState.receiveCardData !is SwapCardState.SwapCardData) return uiState
val patchedSendCardData = uiState.sendCardData.copy(
isBalanceHidden = isBalanceHidden,
)
@@ -666,11 +726,26 @@ internal class StateBuilder(
return "$firstAddressPart...$secondAddressPart"
}
+ private fun CryptoCurrencyStatus.getFormattedAmount(): String {
+ val amount = value.amount ?: return UNKNOWN_AMOUNT_SIGN
+
+ return BigDecimalFormatter.formatCryptoAmount(amount, currency.symbol, currency.decimals)
+ }
+
+ @Suppress("UnusedPrivateMember")
+ private fun CryptoCurrencyStatus.getFormattedFiatAmount(): String {
+ val fiatAmount = value.fiatAmount ?: return UNKNOWN_AMOUNT_SIGN
+ val appCurrency = appCurrencyProvider()
+
+ return BigDecimalFormatter.formatFiatAmount(fiatAmount, appCurrency.code, appCurrency.symbol)
+ }
+
private companion object {
const val ADDRESS_MIN_LENGTH = 11
const val ADDRESS_FIRST_PART_LENGTH = 7
const val ADDRESS_SECOND_PART_LENGTH = 4
private const val PRICE_IMPACT_THRESHOLD = 0.1
private const val HUNDRED_PERCENTS = 100
+ private const val UNKNOWN_AMOUNT_SIGN = "—"
}
}
\ No newline at end of file
diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/SwapScreenContent.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/SwapScreenContent.kt
index 1ea66c1e90..153e3cd1b4 100644
--- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/SwapScreenContent.kt
+++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/SwapScreenContent.kt
@@ -145,48 +145,24 @@ private fun MainInfo(state: SwapStateHolder) {
}
val (topCard, bottomCard, button) = createRefs()
val priceImpactWarning = state.warnings.filterIsInstance().firstOrNull()
- TransactionCard(
- type = state.sendCardData.type,
- balance = if (state.sendCardData.isBalanceHidden) {
- STARS
- } else {
- state.sendCardData.balance
- },
- textFieldValue = state.sendCardData.amountTextFieldValue,
- amountEquivalent = state.sendCardData.amountEquivalent,
- tokenIconUrl = state.sendCardData.tokenIconUrl ?: "",
- tokenCurrency = state.sendCardData.tokenCurrency,
- priceImpact = priceImpactWarning,
- networkIconRes = if (state.sendCardData.isNotNativeToken) networkIconRes else null,
- iconPlaceholder = state.sendCardData.coinId?.let {
- getActiveIconResByCoinId(it)
- },
- onChangeTokenClick = if (state.sendCardData.canSelectAnotherToken) state.onSelectTokenClick else null,
+ TransactionCardData(
+ priceImpactWarning = priceImpactWarning,
+ networkIconRes = networkIconRes,
+ swapCardState = state.sendCardData,
modifier = Modifier.constrainAs(topCard) {
top.linkTo(parent.top)
},
+ onSelectTokenClick = state.onSelectTokenClick,
)
val marginCard = TangemTheme.dimens.spacing16
- TransactionCard(
- type = state.receiveCardData.type,
- balance = if (state.receiveCardData.isBalanceHidden) STARS else state.receiveCardData.balance,
- textFieldValue = state.receiveCardData.amountTextFieldValue,
- amountEquivalent = state.receiveCardData.amountEquivalent,
- tokenIconUrl = state.receiveCardData.tokenIconUrl ?: "",
- tokenCurrency = state.receiveCardData.tokenCurrency,
- priceImpact = priceImpactWarning,
- networkIconRes = if (state.receiveCardData.isNotNativeToken) networkIconRes else null,
- iconPlaceholder = state.receiveCardData.coinId?.let {
- getActiveIconResByCoinId(it)
- },
- onChangeTokenClick = if (state.receiveCardData.canSelectAnotherToken) {
- state.onSelectTokenClick
- } else {
- null
- },
+ TransactionCardData(
+ priceImpactWarning = priceImpactWarning,
+ networkIconRes = networkIconRes,
+ swapCardState = state.receiveCardData,
modifier = Modifier.constrainAs(bottomCard) {
top.linkTo(topCard.bottom, margin = marginCard)
},
+ onSelectTokenClick = state.onSelectTokenClick,
)
val marginButton = TangemTheme.dimens.spacing32
SwapButton(
@@ -200,6 +176,48 @@ private fun MainInfo(state: SwapStateHolder) {
}
}
+@Composable
+private fun TransactionCardData(
+ priceImpactWarning: SwapWarning.HighPriceImpact?,
+ networkIconRes: Int?,
+ swapCardState: SwapCardState,
+ onSelectTokenClick: (() -> Unit)?,
+ modifier: Modifier = Modifier,
+) {
+ when (swapCardState) {
+ is SwapCardState.Empty -> {
+ TransactionCardEmpty(
+ type = swapCardState.type,
+ amountEquivalent = swapCardState.amountEquivalent,
+ textFieldValue = swapCardState.amountTextFieldValue,
+ onChangeTokenClick = if (swapCardState.canSelectAnotherToken) onSelectTokenClick else null,
+ modifier = modifier,
+ )
+ }
+ is SwapCardState.SwapCardData -> {
+ TransactionCard(
+ type = swapCardState.type,
+ balance = if (swapCardState.isBalanceHidden) {
+ STARS
+ } else {
+ swapCardState.balance
+ },
+ textFieldValue = swapCardState.amountTextFieldValue,
+ amountEquivalent = swapCardState.amountEquivalent,
+ tokenIconUrl = swapCardState.tokenIconUrl ?: "",
+ tokenCurrency = swapCardState.tokenCurrency,
+ priceImpact = priceImpactWarning,
+ networkIconRes = if (swapCardState.isNotNativeToken) networkIconRes else null,
+ iconPlaceholder = swapCardState.coinId?.let {
+ getActiveIconResByCoinId(it)
+ },
+ onChangeTokenClick = if (swapCardState.canSelectAnotherToken) onSelectTokenClick else null,
+ modifier = modifier,
+ )
+ }
+ }
+}
+
@OptIn(ExperimentalMaterialApi::class)
@Composable
private fun SwapButton(state: SwapStateHolder, modifier: Modifier = Modifier) {
@@ -268,7 +286,8 @@ private fun FeeItem(feeState: FeeState, currency: String) {
}
}
is FeeState.Empty -> {
- SmallInfoCard(startText = titleString, endText = "")
+ // show nothing
+ // SmallInfoCard(startText = titleString, endText = "")
}
}
}
@@ -355,7 +374,7 @@ private fun MainButton(state: SwapStateHolder, onPermissionWarningClick: () -> U
// region preview
-private val sendCard = SwapCardData(
+private val sendCard = SwapCardState.SwapCardData(
type = TransactionCardType.SendCard({}) {},
amountTextFieldValue = TextFieldValue(),
amountEquivalent = "1 000 000",
@@ -368,7 +387,7 @@ private val sendCard = SwapCardData(
isBalanceHidden = false,
)
-private val receiveCard = SwapCardData(
+private val receiveCard = SwapCardState.SwapCardData(
type = TransactionCardType.ReceiveCard(),
amountTextFieldValue = TextFieldValue(),
amountEquivalent = "1 000 000",
diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/TransactionCard.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/TransactionCard.kt
index 3cbd35a23f..d5996c36a5 100644
--- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/TransactionCard.kt
+++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/TransactionCard.kt
@@ -68,7 +68,7 @@ fun TransactionCard(
verticalArrangement = Arrangement.Top,
horizontalAlignment = Alignment.Start,
) {
- Header(balance = balance, type = type)
+ Header(balance = stringResource(R.string.common_balance, balance), type = type)
Content(
type = type,
@@ -106,6 +106,67 @@ fun TransactionCard(
}
}
+@Composable
+fun TransactionCardEmpty(
+ type: TransactionCardType,
+ amountEquivalent: String?,
+ textFieldValue: TextFieldValue?,
+ modifier: Modifier = Modifier,
+ onChangeTokenClick: (() -> Unit)? = null,
+) {
+ Card(
+ shape = RoundedCornerShape(TangemTheme.dimens.radius12),
+ backgroundColor = TangemTheme.colors.background.primary,
+ elevation = TangemTheme.dimens.elevation2,
+ modifier = modifier,
+ ) {
+ Box(modifier = Modifier.fillMaxSize()) {
+ Column(
+ modifier = Modifier
+ .fillMaxWidth(),
+ verticalArrangement = Arrangement.Top,
+ horizontalAlignment = Alignment.Start,
+ ) {
+ Header(
+ balance = stringResource(id = R.string.swapping_token_not_available),
+ type = type,
+ )
+
+ Content(
+ type = type,
+ amountEquivalent = amountEquivalent,
+ textFieldValue = textFieldValue,
+ priceImpact = null,
+ )
+ }
+
+ Box(modifier = Modifier.align(Alignment.BottomEnd)) {
+ Token(
+ tokenIconUrl = "",
+ tokenCurrency = "",
+ iconPlaceholder = R.drawable.ic_no_token_44,
+ )
+ }
+
+ if (onChangeTokenClick != null) {
+ Box(modifier = Modifier.align(Alignment.CenterEnd)) {
+ ChangeTokenSelector()
+ }
+ Box(
+ Modifier
+ .align(Alignment.CenterEnd)
+ .height(TangemTheme.dimens.size116)
+ .width(TangemTheme.dimens.size102)
+ .clickable(
+ indication = rememberRipple(bounded = false),
+ interactionSource = remember { MutableInteractionSource() },
+ ) { onChangeTokenClick() },
+ )
+ }
+ }
+ }
+}
+
@Composable
private fun Header(type: TransactionCardType, balance: String, modifier: Modifier = Modifier) {
Row(
@@ -134,7 +195,7 @@ private fun Header(type: TransactionCardType, balance: String, modifier: Modifie
SpacerW16()
if (balance.isNotBlank()) {
Text(
- text = stringResource(R.string.common_balance, balance),
+ text = balance,
color = TangemTheme.colors.text.tertiary,
style = MaterialTheme.typography.body2,
modifier = Modifier
diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/viewmodels/SwapProcessDataState.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/viewmodels/SwapProcessDataState.kt
index c9018a2345..9c756453d6 100644
--- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/viewmodels/SwapProcessDataState.kt
+++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/viewmodels/SwapProcessDataState.kt
@@ -1,6 +1,6 @@
package com.tangem.feature.swap.viewmodels
-import com.tangem.domain.tokens.model.CryptoCurrency
+import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.feature.swap.domain.models.domain.Currency
import com.tangem.feature.swap.domain.models.ui.RequestApproveStateData
import com.tangem.feature.swap.domain.models.ui.SwapStateData
@@ -14,8 +14,8 @@ data class SwapProcessDataState(
val fromCurrency: Currency? = null,
@Deprecated("used in old swap mechanism")
val toCurrency: Currency? = null,
- val fromCryptoCurrency: CryptoCurrency? = null,
- val toCryptoCurrency: CryptoCurrency? = null,
+ val fromCryptoCurrency: CryptoCurrencyStatus? = null,
+ val toCryptoCurrency: CryptoCurrencyStatus? = null,
// Amount from input
val amount: String? = null,
val approveDataModel: RequestApproveStateData? = null,
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 0f2d531f35..68b7f39e22 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
@@ -11,7 +11,9 @@ import com.tangem.core.ui.utils.InputNumberFormatter
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
+import com.tangem.domain.tokens.GetCryptoCurrencyStatusSyncUseCase
import com.tangem.domain.tokens.model.CryptoCurrency
+import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.feature.swap.analytics.SwapEvents
import com.tangem.feature.swap.domain.BlockchainInteractor
import com.tangem.feature.swap.domain.SwapInteractor
@@ -49,11 +51,13 @@ internal class SwapViewModel @Inject constructor(
private val analyticsEventHandler: AnalyticsEventHandler,
private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
+ private val getCryptoCurrencyStatusUseCase: GetCryptoCurrencyStatusSyncUseCase,
savedStateHandle: SavedStateHandle,
) : ViewModel(), DefaultLifecycleObserver {
private val initialCryptoCurrency: CryptoCurrency = savedStateHandle[SwapFragment.CURRENCY_BUNDLE_KEY]
?: error("no expected parameter CryptoCurrency found`")
+ private lateinit var initialCryptoCurrencyStatus: CryptoCurrencyStatus
private var isBalanceHidden = true
@@ -88,11 +92,20 @@ internal class SwapViewModel @Inject constructor(
get() = swapRouter.currentScreen
init {
- swapInteractor.initDerivationPathAndNetwork(
- derivationPath = initialCryptoCurrency.network.derivationPath.value,
- network = initialCryptoCurrency.network,
- )
- initTokens()
+ viewModelScope.launch(dispatchers.io) {
+ swapInteractor.getSelectedWallet()?.let {
+ initialCryptoCurrencyStatus =
+ requireNotNull(getCryptoCurrencyStatusUseCase(it.walletId, initialCryptoCurrency.id).getOrNull()) {
+ "Failed to get initial crypto currency status"
+ }
+
+ swapInteractor.initDerivationPathAndNetwork(
+ derivationPath = initialCryptoCurrency.network.derivationPath.value,
+ network = initialCryptoCurrency.network,
+ )
+ initTokens()
+ }
+ }
}
override fun onCreate(owner: LifecycleOwner) {
@@ -137,44 +150,38 @@ internal class SwapViewModel @Inject constructor(
runCatching(dispatchers.io) {
swapInteractor.getTokensDataState(initialCryptoCurrency)
}.onSuccess { state ->
- dataState = dataState.copy(
- fromCryptoCurrency = initialCryptoCurrency,
- toCryptoCurrency = state.toGroup.available.first().currencyStatus.currency,
- tokensDataState = state,
- )
-
updateTokensState(state)
- startLoadingQuotes(
- fromToken = initialCryptoCurrency,
- toToken = state.toGroup.available.first().currencyStatus.currency,
- amount = lastAmount.value,
- )
+ applyInitialTokenChoice(state, selectInitialCurrencyToSwap(state))
}.onFailure {
Timber.tag(loggingTag).e(it)
}
}
+ }
- // 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)
- // }
- // }
+ private fun applyInitialTokenChoice(state: TokensDataStateExpress, selectedCurrency: CryptoCurrencyStatus?) {
+ val fromCurrencyStatus = initialCryptoCurrencyStatus
+ dataState = dataState.copy(
+ fromCryptoCurrency = fromCurrencyStatus,
+ toCryptoCurrency = selectedCurrency,
+ tokensDataState = state,
+ )
+ if (selectedCurrency == null) {
+ uiState = stateBuilder.createNoAvailableTokensToSwapState(
+ uiStateHolder = uiState,
+ fromToken = fromCurrencyStatus,
+ )
+ } else {
+ startLoadingQuotes(
+ fromToken = fromCurrencyStatus.currency,
+ toToken = selectedCurrency.currency,
+ amount = lastAmount.value,
+ )
+ }
+ }
+
+ private fun selectInitialCurrencyToSwap(state: TokensDataStateExpress): CryptoCurrencyStatus? {
+ // todo add algorithm to select initial currency
+ return state.toGroup.available.firstOrNull()?.currencyStatus
}
private fun updateTokensState(dataState: TokensDataStateExpress) {
@@ -203,7 +210,7 @@ internal class SwapViewModel @Inject constructor(
val toCurrency = dataState.toCryptoCurrency
val amount = dataState.amount
if (fromCurrency != null && toCurrency != null && amount != null) {
- startLoadingQuotes(fromCurrency, toCurrency, amount)
+ startLoadingQuotes(fromCurrency.currency, toCurrency.currency, amount)
}
}
@@ -285,8 +292,8 @@ internal class SwapViewModel @Inject constructor(
swapInteractor.onSwap(
networkId = dataState.networkId,
swapStateData = requireNotNull(dataState.swapDataModel),
- currencyToSend = requireNotNull(dataState.fromCryptoCurrency),
- currencyToGet = requireNotNull(dataState.toCryptoCurrency),
+ currencyToSend = requireNotNull(dataState.fromCryptoCurrency?.currency),
+ currencyToGet = requireNotNull(dataState.toCryptoCurrency?.currency),
amountToSwap = requireNotNull(dataState.amount),
fee = requireNotNull(dataState.selectedFee),
)
@@ -335,10 +342,10 @@ internal class SwapViewModel @Inject constructor(
approveData = requireNotNull(dataState.approveDataModel) {
"dataState.approveDataModel might not be null"
},
- forTokenContractAddress = (dataState.fromCryptoCurrency as? CryptoCurrency.Token)
+ forTokenContractAddress = (dataState.fromCryptoCurrency?.currency as? CryptoCurrency.Token)
?.contractAddress
?: "",
- fromToken = requireNotNull(dataState.fromCryptoCurrency) {
+ fromToken = requireNotNull(dataState.fromCryptoCurrency?.currency) {
"dataState.fromCurrency might not be null"
},
approveType = requireNotNull(uiState.permissionState as? SwapPermissionState.ReadyForRequest) {
@@ -384,28 +391,34 @@ internal class SwapViewModel @Inject constructor(
private fun onTokenSelect(id: String) {
val tokens = dataState.tokensDataState ?: return
- val foundToken = tokens.toGroup.available.firstOrNull {
- it.currencyStatus.currency.id.value == id
+ val foundToken = if (isOrderReversed) {
+ tokens.fromGroup.available.firstOrNull {
+ it.currencyStatus.currency.id.value == id
+ }
+ } else {
+ tokens.toGroup.available.firstOrNull {
+ it.currencyStatus.currency.id.value == id
+ }
}
analyticsEventHandler.send(
event = SwapEvents.SearchTokenClicked(currencySymbol = foundToken?.currencyStatus?.currency?.symbol),
)
if (foundToken != null) {
- val fromToken: CryptoCurrency
- val toToken: CryptoCurrency
+ val fromToken: CryptoCurrencyStatus
+ val toToken: CryptoCurrencyStatus
if (isOrderReversed) {
- fromToken = foundToken.currencyStatus.currency
- toToken = initialCryptoCurrency
+ fromToken = foundToken.currencyStatus
+ toToken = initialCryptoCurrencyStatus
} else {
- fromToken = initialCryptoCurrency
- toToken = foundToken.currencyStatus.currency
+ fromToken = initialCryptoCurrencyStatus
+ toToken = foundToken.currencyStatus
}
dataState = dataState.copy(
fromCryptoCurrency = fromToken,
toCryptoCurrency = toToken,
)
- startLoadingQuotes(fromToken, toToken, lastAmount.value)
+ startLoadingQuotes(fromToken.currency, toToken.currency, lastAmount.value)
swapRouter.openScreen(SwapNavScreen.Main)
}
}
@@ -419,13 +432,13 @@ internal class SwapViewModel @Inject constructor(
toCryptoCurrency = newToToken,
)
isOrderReversed = !isOrderReversed
- val decimals = blockchainInteractor.getTokenDecimals(newFromToken)
+ val decimals = newFromToken.currency.decimals
lastAmount.value = cutAmountWithDecimals(decimals, lastAmount.value)
uiState = stateBuilder.updateSwapAmount(
uiState,
inputNumberFormatter.formatWithThousands(lastAmount.value, decimals),
)
- startLoadingQuotes(newFromToken, newToToken, lastAmount.value)
+ startLoadingQuotes(newFromToken.currency, newToToken.currency, lastAmount.value)
}
}
@@ -433,20 +446,20 @@ internal class SwapViewModel @Inject constructor(
val fromToken = dataState.fromCryptoCurrency
val toToken = dataState.toCryptoCurrency
if (fromToken != null && toToken != null) {
- val decimals = blockchainInteractor.getTokenDecimals(fromToken)
+ val decimals = fromToken.currency.decimals
val cutValue = cutAmountWithDecimals(decimals, value)
lastAmount.value = cutValue
uiState =
stateBuilder.updateSwapAmount(uiState, inputNumberFormatter.formatWithThousands(cutValue, decimals))
amountDebouncer.debounce(viewModelScope, DEBOUNCE_AMOUNT_DELAY) {
- startLoadingQuotes(fromToken, toToken, lastAmount.value)
+ startLoadingQuotes(fromToken.currency, toToken.currency, lastAmount.value)
}
}
}
private fun onMaxAmountClicked() {
dataState.fromCryptoCurrency?.let {
- val balance = swapInteractor.getTokenBalance(initialCryptoCurrency.network.id.value, it)
+ val balance = swapInteractor.getTokenBalance(initialCryptoCurrency.network.id.value, it.currency)
onAmountChanged(balance.formatToUIRepresentation())
}
}
@@ -522,7 +535,7 @@ internal class SwapViewModel @Inject constructor(
dataState = dataState.copy(selectedFee = feeItem.data)
val spendAmount = dataState.amount?.let { amount ->
val fromToken = dataState.fromCryptoCurrency ?: return@let null
- swapInteractor.getSwapAmountForToken(amount, fromToken)
+ swapInteractor.getSwapAmountForToken(amount, fromToken.currency)
} ?: dataState.approveDataModel?.fromTokenAmount
spendAmount ?: return@UiActions
val fromToken = dataState.fromCryptoCurrency ?: return@UiActions
@@ -531,7 +544,7 @@ internal class SwapViewModel @Inject constructor(
fee = feeItem.data.feeValue,
spendAmount = spendAmount,
networkId = dataState.networkId,
- fromToken = fromToken,
+ fromToken = fromToken.currency,
)
uiState = stateBuilder.updateFeeSelectedItem(uiState, feeItem, isFeeEnough)
}