Updated on 2026-08-14
This commit is contained in:
commit
fa4b51cebe
13 changed files with 97 additions and 60 deletions
|
|
@ -11,6 +11,7 @@ import com.tangem.domain.wallets.legacy.WalletsStateHolder
|
|||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.tap.common.entities.FiatCurrency
|
||||
import com.tangem.tap.common.extensions.dispatchOnMain
|
||||
import com.tangem.tap.common.extensions.dispatchWithMain
|
||||
import com.tangem.tap.common.extensions.onUserWalletSelected
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
import com.tangem.tap.domain.TangemSdkManager
|
||||
|
|
@ -69,6 +70,10 @@ class AppStateHolder @Inject constructor() : WalletsStateHolder, ReduxNavControl
|
|||
mainStore?.dispatch(action)
|
||||
}
|
||||
|
||||
override suspend fun dispatchWithMain(action: Action) {
|
||||
mainStore?.dispatchWithMain(action)
|
||||
}
|
||||
|
||||
override suspend fun onUserWalletSelected(userWallet: UserWallet) {
|
||||
mainStore?.onUserWalletSelected(userWallet)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -198,6 +198,7 @@
|
|||
<string name="express_choose_providers_subtitle">Провайдеры проводят транзакции, обеспечивая плавный и эффективный обмен токенами</string>
|
||||
<string name="express_choose_providers_title">Выберите провайдера</string>
|
||||
<string name="express_estimated_amount">Курс обмена</string>
|
||||
<string name="express_more_providers_soon">Больше провайдеров на подходе.\nСледите за обновлениями!</string>
|
||||
<string name="express_exchange_notification_failed_text">Чтобы вернуть ваши деньги, посетите сайт провайдера</string>
|
||||
<string name="express_exchange_notification_failed_title">Операция не выполнена провайдером</string>
|
||||
<string name="express_exchange_notification_verification_text">Посетите сайт провайдера для проверки</string>
|
||||
|
|
|
|||
|
|
@ -196,6 +196,7 @@
|
|||
<string name="express_cex_status_button_title">Status</string>
|
||||
<string name="express_choose_providers_subtitle">Providers facilitate transactions, ensuring smooth and efficient token swaps</string>
|
||||
<string name="express_choose_providers_title">Choose provider</string>
|
||||
<string name="express_more_providers_soon">More providers are coming soon.\nStay tuned!</string>
|
||||
<string name="express_estimated_amount">Estimated amount</string>
|
||||
<string name="express_exchange_by">Exchange by %s</string>
|
||||
<string name="express_exchange_notification_failed_text">Visit provider’s website to refund your money</string>
|
||||
|
|
|
|||
|
|
@ -7,5 +7,7 @@ interface ReduxStateHolder {
|
|||
|
||||
fun dispatch(action: Action)
|
||||
|
||||
suspend fun dispatchWithMain(action: Action)
|
||||
|
||||
suspend fun onUserWalletSelected(userWallet: UserWallet)
|
||||
}
|
||||
|
|
@ -2,7 +2,6 @@ package com.tangem.feature.swap.domain
|
|||
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
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.IncludeFeeInAmount
|
||||
|
|
@ -15,8 +14,6 @@ interface SwapInteractor {
|
|||
|
||||
suspend fun getTokensDataState(currency: CryptoCurrency): TokensDataStateExpress
|
||||
|
||||
fun initDerivationPathAndNetwork(derivationPath: String?, network: Network)
|
||||
|
||||
/**
|
||||
* Gives permission to swap, this starts scan card process
|
||||
*
|
||||
|
|
@ -30,7 +27,6 @@ interface SwapInteractor {
|
|||
* Find best quote for given tokens to swap
|
||||
* under the hood calls different methods to receive data, depends on permission for given token
|
||||
*
|
||||
* @param networkId network for tokens
|
||||
* @param fromToken [Currency] from which want to swap
|
||||
* @param toToken [Currency] that receive after swap
|
||||
* @param amountToSwap amount you want to swap
|
||||
|
|
@ -39,7 +35,6 @@ interface SwapInteractor {
|
|||
*/
|
||||
@Throws(IllegalStateException::class)
|
||||
suspend fun findBestQuote(
|
||||
networkId: String,
|
||||
fromToken: CryptoCurrencyStatus,
|
||||
toToken: CryptoCurrencyStatus,
|
||||
providers: List<SwapProvider>,
|
||||
|
|
@ -62,7 +57,6 @@ interface SwapInteractor {
|
|||
@Throws(IllegalStateException::class)
|
||||
suspend fun onSwap(
|
||||
swapProvider: SwapProvider,
|
||||
networkId: String,
|
||||
swapData: SwapDataModel?,
|
||||
currencyToSend: CryptoCurrencyStatus,
|
||||
currencyToGet: CryptoCurrencyStatus,
|
||||
|
|
@ -76,7 +70,6 @@ interface SwapInteractor {
|
|||
selectedFee: FeeType,
|
||||
fromToken: CryptoCurrencyStatus,
|
||||
amountToSwap: String,
|
||||
networkId: String,
|
||||
): SwapState.QuotesLoadedState
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -62,7 +62,6 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
|
||||
private val swapCurrencyConverter = SwapCurrencyConverter()
|
||||
private val amountFormatter = AmountFormatter()
|
||||
private var derivationPath: String? = null
|
||||
private var network: Network? = null
|
||||
|
||||
override suspend fun getTokensDataState(currency: CryptoCurrency): TokensDataStateExpress {
|
||||
|
|
@ -80,7 +79,7 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
.filter {
|
||||
val currencyFilter = it.currency.network.backendId != currency.network.backendId ||
|
||||
it.currency.getContractAddress() != currency.getContractAddress()
|
||||
val statusFilter = it.value is CryptoCurrencyStatus.Loaded
|
||||
val statusFilter = it.value is CryptoCurrencyStatus.Loaded || it.value is CryptoCurrencyStatus.NoAccount
|
||||
val notCustomTokenFilter = !it.currency.isCustom
|
||||
statusFilter && currencyFilter && notCustomTokenFilter
|
||||
}
|
||||
|
|
@ -182,14 +181,9 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
return repository.getPairs(initialCurrency, currenciesList)
|
||||
}
|
||||
|
||||
@Deprecated("used in old swap mechanism")
|
||||
override fun initDerivationPathAndNetwork(derivationPath: String?, network: Network) {
|
||||
this.derivationPath = derivationPath
|
||||
this.network = network
|
||||
}
|
||||
|
||||
@Deprecated("used in old swap mechanism")
|
||||
override suspend fun givePermissionToSwap(networkId: String, permissionOptions: PermissionOptions): TxState {
|
||||
val derivationPath = permissionOptions.fromToken.network.derivationPath.value
|
||||
val dataToSign = if (permissionOptions.approveType == SwapApproveType.UNLIMITED) {
|
||||
getApproveData(
|
||||
networkId = networkId,
|
||||
|
|
@ -233,7 +227,6 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
|
||||
@Deprecated("used in old swap mechanism")
|
||||
override suspend fun findBestQuote(
|
||||
networkId: String,
|
||||
fromToken: CryptoCurrencyStatus,
|
||||
toToken: CryptoCurrencyStatus,
|
||||
providers: List<SwapProvider>,
|
||||
|
|
@ -249,7 +242,7 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
}
|
||||
val amount = SwapAmount(amountDecimal, getTokenDecimals(fromToken.currency))
|
||||
val isBalanceWithoutFeeEnough = isBalanceEnough(fromToken, amount, null)
|
||||
|
||||
val networkId = fromToken.currency.network.backendId
|
||||
when (provider.type) {
|
||||
ExchangeProviderType.DEX -> {
|
||||
manageDex(
|
||||
|
|
@ -310,7 +303,10 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
|
||||
if (isAllowedToSpend && allowPermissionsHandler.isAddressAllowanceInProgress(fromTokenAddress)) {
|
||||
allowPermissionsHandler.removeAddressFromProgress(fromTokenAddress)
|
||||
transactionManager.updateWalletManager(networkId, derivationPath)
|
||||
transactionManager.updateWalletManager(
|
||||
networkId,
|
||||
fromToken.currency.network.derivationPath.value,
|
||||
)
|
||||
}
|
||||
return if (isAllowedToSpend && isBalanceWithoutFeeEnough) {
|
||||
provider to loadDexSwapData(
|
||||
|
|
@ -361,7 +357,6 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
|
||||
override suspend fun onSwap(
|
||||
swapProvider: SwapProvider,
|
||||
networkId: String,
|
||||
swapData: SwapDataModel?,
|
||||
currencyToSend: CryptoCurrencyStatus,
|
||||
currencyToGet: CryptoCurrencyStatus,
|
||||
|
|
@ -389,7 +384,7 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
}
|
||||
ExchangeProviderType.DEX -> {
|
||||
onSwapDex(
|
||||
networkId = networkId,
|
||||
networkId = currencyToSend.currency.network.backendId,
|
||||
swapData = requireNotNull(swapData),
|
||||
currencyToSend = currencyToSend.currency,
|
||||
currencyToGet = currencyToGet.currency,
|
||||
|
|
@ -405,7 +400,6 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
selectedFee: FeeType,
|
||||
fromToken: CryptoCurrencyStatus,
|
||||
amountToSwap: String,
|
||||
networkId: String,
|
||||
): SwapState.QuotesLoadedState {
|
||||
val amountDecimal = toBigDecimalOrNull(amountToSwap)
|
||||
if (amountDecimal == null || amountDecimal.signum() == 0) {
|
||||
|
|
@ -413,7 +407,7 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
}
|
||||
val amount = SwapAmount(amountDecimal, getTokenDecimals(fromToken.currency))
|
||||
val includeFeeInAmount = getIncludeFeeInAmount(
|
||||
networkId = networkId,
|
||||
networkId = fromToken.currency.network.backendId,
|
||||
txFee = state.txFee,
|
||||
amount = amount,
|
||||
fromToken = fromToken.currency,
|
||||
|
|
@ -422,6 +416,7 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
return state.copy(
|
||||
permissionState = PermissionDataState.Empty,
|
||||
preparedSwapConfigState = state.preparedSwapConfigState.copy(
|
||||
isFeeEnough = includeFeeInAmount !is IncludeFeeInAmount.BalanceNotEnough,
|
||||
isBalanceEnough = includeFeeInAmount !is IncludeFeeInAmount.BalanceNotEnough,
|
||||
includeFeeInAmount = includeFeeInAmount,
|
||||
),
|
||||
|
|
@ -438,6 +433,7 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
): TxState {
|
||||
val amountDecimal = requireNotNull(toBigDecimalOrNull(amountToSwap)) { "wrong amount format" }
|
||||
val amount = SwapAmount(amountDecimal, getTokenDecimals(currencyToSend))
|
||||
val derivationPath = currencyToSend.network.derivationPath.value
|
||||
val result = transactionManager.sendTransaction(
|
||||
txData = SwapTxData(
|
||||
networkId = networkId,
|
||||
|
|
@ -481,6 +477,7 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
@Suppress("LongMethod")
|
||||
private suspend fun onSwapCex(
|
||||
currencyToSend: CryptoCurrencyStatus,
|
||||
currencyToGet: CryptoCurrencyStatus,
|
||||
|
|
@ -519,6 +516,7 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
|
||||
val externalUrl = (exchangeData.transaction as? ExpressTransactionModel.CEX)?.externalTxUrl
|
||||
|
||||
val derivationPath = currencyToSend.currency.network.derivationPath.value
|
||||
return result.fold(
|
||||
ifLeft = {
|
||||
when (it) {
|
||||
|
|
@ -659,7 +657,7 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
val allowance = repository.getAllowance(
|
||||
userWalletId = userWallet.walletId,
|
||||
networkId = networkId,
|
||||
derivationPath = derivationPath,
|
||||
derivationPath = fromToken.network.derivationPath.value,
|
||||
tokenDecimalCount = getTokenDecimals(fromToken),
|
||||
tokenAddress = getTokenAddress(fromToken),
|
||||
spenderAddress = spenderAddress,
|
||||
|
|
@ -832,7 +830,10 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
}
|
||||
|
||||
val tokenForFeeBalance =
|
||||
userWalletManager.getNativeTokenBalance(networkId, derivationPath) ?: ProxyAmount.empty()
|
||||
userWalletManager.getNativeTokenBalance(
|
||||
networkId,
|
||||
fromToken.network.derivationPath.value,
|
||||
) ?: ProxyAmount.empty()
|
||||
|
||||
if (amount.value > tokenForFeeBalance.value) {
|
||||
return IncludeFeeInAmount.BalanceNotEnough
|
||||
|
|
@ -907,7 +908,7 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
destinationAddress = swapData.transaction.txTo,
|
||||
increaseBy = INCREASE_GAS_LIMIT_BY,
|
||||
data = (swapData.transaction as ExpressTransactionModel.DEX).txData,
|
||||
derivationPath = derivationPath,
|
||||
derivationPath = fromToken.currency.network.derivationPath.value,
|
||||
)
|
||||
val txFeeState = when (feeData) {
|
||||
is ProxyFees.MultipleFees -> feeData.proxyFeesToFeeState(networkId)
|
||||
|
|
@ -1048,6 +1049,7 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
permissionState = PermissionDataState.PermissionLoading,
|
||||
)
|
||||
}
|
||||
val derivationPath = fromToken.network.derivationPath.value
|
||||
// setting up amount for approve with given amount for swap [SwapApproveType.Limited]
|
||||
val transactionData = getApproveData(
|
||||
networkId = networkId,
|
||||
|
|
@ -1091,7 +1093,7 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
permissionState = PermissionDataState.PermissionReadyForRequest(
|
||||
currency = fromToken.symbol,
|
||||
amount = INFINITY_SYMBOL,
|
||||
walletAddress = getWalletAddress(networkId),
|
||||
walletAddress = getWalletAddress(networkId, derivationPath),
|
||||
spenderAddress = getTokenAddress(fromToken),
|
||||
requestApproveData = RequestApproveStateData(
|
||||
fee = feeState,
|
||||
|
|
@ -1262,7 +1264,7 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private suspend fun getWalletAddress(networkId: String): String {
|
||||
private suspend fun getWalletAddress(networkId: String, derivationPath: String?): String {
|
||||
return userWalletManager.getWalletAddress(networkId, derivationPath)
|
||||
}
|
||||
|
||||
|
|
@ -1286,7 +1288,10 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
if (fee == null) {
|
||||
return false
|
||||
}
|
||||
val nativeTokenBalance = userWalletManager.getNativeTokenBalance(networkId, derivationPath)
|
||||
val nativeTokenBalance = userWalletManager.getNativeTokenBalance(
|
||||
networkId,
|
||||
fromToken.network.derivationPath.value,
|
||||
)
|
||||
val percentsToFeeIncrease = BigDecimal.ONE
|
||||
return when (fromToken) {
|
||||
is CryptoCurrency.Coin -> {
|
||||
|
|
|
|||
|
|
@ -4,11 +4,13 @@ import androidx.compose.foundation.background
|
|||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
|
|
@ -55,7 +57,12 @@ private fun ChooseProviderBottomSheetContent(content: ChooseProviderBottomSheetC
|
|||
)
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(TangemTheme.dimens.spacing16)
|
||||
.padding(
|
||||
top = TangemTheme.dimens.spacing16,
|
||||
start = TangemTheme.dimens.spacing16,
|
||||
end = TangemTheme.dimens.spacing16,
|
||||
bottom = TangemTheme.dimens.spacing14,
|
||||
)
|
||||
.background(
|
||||
color = TangemTheme.colors.background.action,
|
||||
shape = TangemTheme.shapes.roundedCornersXMedium,
|
||||
|
|
@ -76,6 +83,23 @@ private fun ChooseProviderBottomSheetContent(content: ChooseProviderBottomSheetC
|
|||
)
|
||||
}
|
||||
}
|
||||
Icon(
|
||||
painterResource(id = R.drawable.ic_lightning_16),
|
||||
contentDescription = null,
|
||||
tint = TangemTheme.colors.icon.informative,
|
||||
modifier = Modifier
|
||||
.align(Alignment.CenterHorizontally),
|
||||
)
|
||||
Text(
|
||||
text = stringResource(R.string.express_more_providers_soon),
|
||||
style = TangemTheme.typography.caption2,
|
||||
color = TangemTheme.colors.icon.informative,
|
||||
modifier = Modifier
|
||||
.padding(top = TangemTheme.dimens.spacing6, bottom = TangemTheme.dimens.spacing16)
|
||||
.padding(horizontal = TangemTheme.dimens.spacing56)
|
||||
.align(Alignment.CenterHorizontally),
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -74,16 +74,15 @@ internal fun SwapScreenContent(state: SwapStateHolder, modifier: Modifier = Modi
|
|||
if (state.warnings.isNotEmpty()) SwapWarnings(warnings = state.warnings)
|
||||
|
||||
MainButton(state = state, onPermissionWarningClick = state.onShowPermissionBottomSheet)
|
||||
}
|
||||
}
|
||||
|
||||
state.tosState?.let {
|
||||
ProviderTos(
|
||||
tosState = it,
|
||||
modifier = Modifier
|
||||
.align(Alignment.BottomCenter)
|
||||
.padding(bottom = TangemTheme.dimens.spacing16),
|
||||
)
|
||||
state.tosState?.let {
|
||||
ProviderTos(
|
||||
tosState = it,
|
||||
modifier = Modifier
|
||||
.padding(top = TangemTheme.dimens.spacing16),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AnimatedVisibility(
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import com.tangem.feature.swap.models.ApproveType
|
|||
|
||||
data class SwapProcessDataState(
|
||||
// Initial network id
|
||||
val networkId: String,
|
||||
val fromCryptoCurrency: CryptoCurrencyStatus? = null,
|
||||
val toCryptoCurrency: CryptoCurrencyStatus? = null,
|
||||
// Amount from input
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ internal class SwapViewModel @Inject constructor(
|
|||
private val amountDebouncer = Debouncer()
|
||||
private val singleTaskScheduler = SingleTaskScheduler<Map<SwapProvider, SwapState>>()
|
||||
|
||||
private var dataState by mutableStateOf(SwapProcessDataState(networkId = initialCryptoCurrency.network.backendId))
|
||||
private var dataState by mutableStateOf(SwapProcessDataState())
|
||||
|
||||
var uiState: SwapStateHolder by mutableStateOf(
|
||||
stateBuilder.createInitialLoadingState(
|
||||
|
|
@ -103,11 +103,6 @@ internal class SwapViewModel @Inject constructor(
|
|||
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()
|
||||
}
|
||||
}
|
||||
|
|
@ -278,7 +273,6 @@ internal class SwapViewModel @Inject constructor(
|
|||
approveDataModel = null,
|
||||
)
|
||||
swapInteractor.findBestQuote(
|
||||
networkId = dataState.networkId,
|
||||
fromToken = fromToken,
|
||||
toToken = toToken,
|
||||
providers = toProvidersList,
|
||||
|
|
@ -438,13 +432,13 @@ internal class SwapViewModel @Inject constructor(
|
|||
Timber.e("Last loaded quotes state is null")
|
||||
return
|
||||
}
|
||||
val fromCurrency = requireNotNull(dataState.fromCryptoCurrency)
|
||||
viewModelScope.launch(dispatchers.main) {
|
||||
runCatching(dispatchers.io) {
|
||||
swapInteractor.onSwap(
|
||||
swapProvider = provider,
|
||||
networkId = dataState.networkId,
|
||||
swapData = dataState.swapDataModel,
|
||||
currencyToSend = requireNotNull(dataState.fromCryptoCurrency),
|
||||
currencyToSend = fromCurrency,
|
||||
currencyToGet = requireNotNull(dataState.toCryptoCurrency),
|
||||
amountToSwap = requireNotNull(dataState.amount),
|
||||
includeFeeInAmount = lastLoadedQuotesState.preparedSwapConfigState.includeFeeInAmount,
|
||||
|
|
@ -454,7 +448,7 @@ internal class SwapViewModel @Inject constructor(
|
|||
when (it) {
|
||||
is TxState.TxSent -> {
|
||||
val url = blockchainInteractor.getExplorerTransactionLink(
|
||||
networkId = dataState.networkId,
|
||||
networkId = fromCurrency.currency.network.backendId,
|
||||
txAddress = it.txAddress,
|
||||
)
|
||||
uiState = stateBuilder.createSuccessState(
|
||||
|
|
@ -528,17 +522,18 @@ internal class SwapViewModel @Inject constructor(
|
|||
is TxFeeState.SingleFeeState -> fee.fee
|
||||
null -> error("Fee should not be null")
|
||||
}
|
||||
val fromToken = requireNotNull(dataState.fromCryptoCurrency?.currency) {
|
||||
"dataState.fromCurrency might not be null"
|
||||
}
|
||||
swapInteractor.givePermissionToSwap(
|
||||
networkId = dataState.networkId,
|
||||
networkId = fromToken.network.backendId,
|
||||
permissionOptions = PermissionOptions(
|
||||
approveData = requireNotNull(dataState.approveDataModel) {
|
||||
"dataState.approveDataModel might not be null"
|
||||
},
|
||||
forTokenContractAddress = (dataState.fromCryptoCurrency?.currency as? CryptoCurrency.Token)
|
||||
?.contractAddress ?: "",
|
||||
fromToken = requireNotNull(dataState.fromCryptoCurrency?.currency) {
|
||||
"dataState.fromCurrency might not be null"
|
||||
},
|
||||
fromToken = fromToken,
|
||||
approveType = requireNotNull(dataState.approveType) {
|
||||
"uiState.permissionState should not be null"
|
||||
}.toDomainApproveType(),
|
||||
|
|
@ -805,7 +800,6 @@ internal class SwapViewModel @Inject constructor(
|
|||
selectedFee = it.feeType,
|
||||
fromToken = fromToken,
|
||||
amountToSwap = amountToSwap,
|
||||
networkId = dataState.networkId,
|
||||
)
|
||||
setupLoadedState(selectedProvider, updatedState, fromToken)
|
||||
}
|
||||
|
|
@ -839,7 +833,11 @@ internal class SwapViewModel @Inject constructor(
|
|||
},
|
||||
onBuyClick = {
|
||||
swapInteractor.getSelectedWallet()?.let {
|
||||
swapRouter.openTokenDetails(it.walletId, swapInteractor.getNativeToken(dataState.networkId))
|
||||
val fromToken = dataState.fromCryptoCurrency ?: return@let
|
||||
swapRouter.openTokenDetails(
|
||||
it.walletId,
|
||||
swapInteractor.getNativeToken(fromToken.currency.network.backendId),
|
||||
)
|
||||
}
|
||||
},
|
||||
onRetryClick = {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="17dp"
|
||||
android:height="16dp"
|
||||
android:viewportWidth="17"
|
||||
android:viewportHeight="16">
|
||||
<path
|
||||
android:pathData="M5.904,6.28L14.027,1.372L9.871,8.57L5.904,6.28ZM12.489,10.082L4.366,14.99L8.522,7.791L12.489,10.082Z"
|
||||
android:fillColor="#C9C9C9"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
||||
|
|
@ -333,7 +333,7 @@ internal class TokenDetailsViewModel @Inject constructor(
|
|||
|
||||
val cryptoCurrencyStatus = cryptoCurrencyStatus ?: return
|
||||
|
||||
viewModelScope.launch(dispatchers.io) {
|
||||
viewModelScope.launch(dispatchers.main) {
|
||||
when (val currency = cryptoCurrencyStatus.currency) {
|
||||
is CryptoCurrency.Coin -> {
|
||||
reduxStateHolder.dispatch(
|
||||
|
|
@ -363,7 +363,7 @@ internal class TokenDetailsViewModel @Inject constructor(
|
|||
.distinctUntilChanged()
|
||||
.firstOrNull()
|
||||
|
||||
reduxStateHolder.dispatch(
|
||||
reduxStateHolder.dispatchWithMain(
|
||||
action = TradeCryptoAction.New.SendToken(
|
||||
userWallet = wallet,
|
||||
tokenCurrency = tokenCurrency,
|
||||
|
|
|
|||
|
|
@ -675,7 +675,7 @@ internal class WalletViewModel @Inject constructor(
|
|||
.collectLatest {
|
||||
it.onRight { coinStatus ->
|
||||
uiState = stateFactory.getStateWithClosedBottomSheet()
|
||||
reduxStateHolder.dispatch(
|
||||
reduxStateHolder.dispatchWithMain(
|
||||
action = TradeCryptoAction.New.SendToken(
|
||||
userWallet = userWallet,
|
||||
tokenCurrency = requireNotNull(cryptoCurrencyStatus.currency as? CryptoCurrency.Token),
|
||||
|
|
@ -1163,8 +1163,8 @@ internal class WalletViewModel @Inject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
private fun setupWalletConnectOnWallet(userWallet: UserWallet) {
|
||||
reduxStateHolder.dispatch(
|
||||
private suspend fun setupWalletConnectOnWallet(userWallet: UserWallet) {
|
||||
reduxStateHolder.dispatchWithMain(
|
||||
action = WalletConnectActions.New.SetupUserChains(userWallet = userWallet),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue