Updated on 2026-08-14
This commit is contained in:
parent
687a67632d
commit
52f7454657
14 changed files with 174 additions and 145 deletions
|
|
@ -155,7 +155,7 @@ class TradeCryptoMiddleware {
|
|||
val walletManager = store.state.daggerGraphState
|
||||
.get(DaggerGraphState::walletManagersFacade)
|
||||
.getOrCreateWalletManager(
|
||||
userWallet = action.userWallet,
|
||||
userWalletId = action.userWallet.walletId,
|
||||
blockchain = blockchain,
|
||||
derivationPath = currency.network.derivationPath.value,
|
||||
)
|
||||
|
|
@ -338,7 +338,7 @@ class TradeCryptoMiddleware {
|
|||
val walletManager = store.state.daggerGraphState
|
||||
.get(DaggerGraphState::walletManagersFacade)
|
||||
.getOrCreateWalletManager(
|
||||
userWallet = action.userWallet,
|
||||
userWalletId = action.userWallet.walletId,
|
||||
blockchain = blockchain,
|
||||
derivationPath = currency.network.derivationPath.value,
|
||||
)
|
||||
|
|
@ -379,7 +379,7 @@ class TradeCryptoMiddleware {
|
|||
val walletManager = store.state.daggerGraphState
|
||||
.get(DaggerGraphState::walletManagersFacade)
|
||||
.getOrCreateWalletManager(
|
||||
userWallet = action.userWallet,
|
||||
userWalletId = action.userWallet.walletId,
|
||||
blockchain = blockchain,
|
||||
derivationPath = currency.network.derivationPath.value,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -419,7 +419,7 @@ class TransactionManagerImpl(
|
|||
appStateHolder.userWalletsListManager?.selectedUserWalletSync,
|
||||
) { "userWallet or userWalletsListManager is null" }
|
||||
walletManagersFacade.getOrCreateWalletManager(
|
||||
selectedUserWallet,
|
||||
selectedUserWallet.walletId,
|
||||
blockchain,
|
||||
derivationPath,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@ class UserWalletManagerImpl(
|
|||
appStateHolder.userWalletsListManager?.selectedUserWalletSync,
|
||||
) { "userWallet or userWalletsListManager is null" }
|
||||
walletManagersFacade.getOrCreateWalletManager(
|
||||
selectedUserWallet,
|
||||
selectedUserWallet.walletId,
|
||||
blockchain,
|
||||
derivationPath,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -61,11 +61,10 @@ class DefaultWalletManagersFacade(
|
|||
network: Network,
|
||||
addressType: AddressType,
|
||||
): String {
|
||||
val userWallet = getUserWallet(userWalletId)
|
||||
val blockchain = Blockchain.fromId(network.id.value)
|
||||
|
||||
val walletManager = getOrCreateWalletManager(
|
||||
userWallet = userWallet,
|
||||
userWalletId = userWalletId,
|
||||
blockchain = blockchain,
|
||||
derivationPath = network.derivationPath.value,
|
||||
)
|
||||
|
|
@ -79,10 +78,9 @@ class DefaultWalletManagersFacade(
|
|||
}
|
||||
|
||||
override suspend fun getTxHistoryState(userWalletId: UserWalletId, network: Network): TxHistoryState {
|
||||
val userWallet = getUserWallet(userWalletId)
|
||||
val blockchain = Blockchain.fromId(network.id.value)
|
||||
val walletManager = getOrCreateWalletManager(
|
||||
userWallet = userWallet,
|
||||
userWalletId = userWalletId,
|
||||
blockchain = blockchain,
|
||||
derivationPath = network.derivationPath.value,
|
||||
)
|
||||
|
|
@ -102,10 +100,9 @@ class DefaultWalletManagersFacade(
|
|||
page: Int,
|
||||
pageSize: Int,
|
||||
): PaginationWrapper<TxHistoryItem> {
|
||||
val userWallet = getUserWallet(userWalletId)
|
||||
val blockchain = Blockchain.fromId(currency.network.id.value)
|
||||
val walletManager = getOrCreateWalletManager(
|
||||
userWallet = userWallet,
|
||||
userWalletId = userWalletId,
|
||||
blockchain = blockchain,
|
||||
derivationPath = currency.network.derivationPath.value,
|
||||
)
|
||||
|
|
@ -154,7 +151,11 @@ class DefaultWalletManagersFacade(
|
|||
return UpdateWalletManagerResult.MissedDerivation
|
||||
}
|
||||
|
||||
val walletManager = getOrCreateWalletManager(userWallet, blockchain, derivationPath)
|
||||
val walletManager = getOrCreateWalletManager(
|
||||
userWalletId = userWallet.walletId,
|
||||
blockchain = blockchain,
|
||||
derivationPath = derivationPath,
|
||||
)
|
||||
if (walletManager == null || blockchain == Blockchain.Unknown) {
|
||||
Timber.w("Unable to get a wallet manager for blockchain: $blockchain")
|
||||
return UpdateWalletManagerResult.Unreachable
|
||||
|
|
@ -195,12 +196,11 @@ class DefaultWalletManagersFacade(
|
|||
}
|
||||
|
||||
override suspend fun getOrCreateWalletManager(
|
||||
userWallet: UserWallet,
|
||||
userWalletId: UserWalletId,
|
||||
blockchain: Blockchain,
|
||||
derivationPath: String?,
|
||||
): WalletManager? {
|
||||
val userWalletId = userWallet.walletId
|
||||
|
||||
val userWallet = getUserWallet(userWalletId)
|
||||
var walletManager = walletManagersStore.getSyncOrNull(
|
||||
userWalletId = userWalletId,
|
||||
blockchain = blockchain,
|
||||
|
|
@ -221,11 +221,10 @@ class DefaultWalletManagersFacade(
|
|||
}
|
||||
|
||||
override suspend fun getAddress(userWalletId: UserWalletId, network: Network): List<Address> {
|
||||
val userWallet = getUserWallet(userWalletId)
|
||||
val blockchain = Blockchain.fromId(network.id.value)
|
||||
|
||||
return getOrCreateWalletManager(
|
||||
userWallet = userWallet,
|
||||
userWalletId = userWalletId,
|
||||
blockchain = blockchain,
|
||||
derivationPath = network.derivationPath.value,
|
||||
)
|
||||
|
|
@ -236,10 +235,9 @@ class DefaultWalletManagersFacade(
|
|||
}
|
||||
|
||||
override suspend fun getRentInfo(userWalletId: UserWalletId, network: Network): CryptoCurrencyWarning.Rent? {
|
||||
val userWallet = getUserWallet(userWalletId)
|
||||
val blockchain = Blockchain.fromId(network.id.value)
|
||||
val manager = getOrCreateWalletManager(
|
||||
userWallet = userWallet,
|
||||
userWalletId = userWalletId,
|
||||
blockchain = blockchain,
|
||||
derivationPath = network.derivationPath.value,
|
||||
)
|
||||
|
|
@ -267,10 +265,9 @@ class DefaultWalletManagersFacade(
|
|||
}
|
||||
|
||||
override suspend fun getExistentialDeposit(userWalletId: UserWalletId, network: Network): BigDecimal? {
|
||||
val userWallet = getUserWallet(userWalletId)
|
||||
val blockchain = Blockchain.fromId(network.id.value)
|
||||
val manager = getOrCreateWalletManager(
|
||||
userWallet = userWallet,
|
||||
userWalletId = userWalletId,
|
||||
blockchain = blockchain,
|
||||
derivationPath = network.derivationPath.value,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import com.tangem.domain.txhistory.models.PaginationWrapper
|
|||
import com.tangem.domain.txhistory.models.TxHistoryItem
|
||||
import com.tangem.domain.txhistory.models.TxHistoryState
|
||||
import com.tangem.domain.walletmanager.model.UpdateWalletManagerResult
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import java.math.BigDecimal
|
||||
|
||||
|
|
@ -72,7 +71,7 @@ interface WalletManagersFacade {
|
|||
|
||||
// TODO: Remove after refactoring
|
||||
suspend fun getOrCreateWalletManager(
|
||||
userWallet: UserWallet,
|
||||
userWalletId: UserWalletId,
|
||||
blockchain: Blockchain,
|
||||
derivationPath: String?,
|
||||
): WalletManager?
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
package com.tangem.feature.swap
|
||||
|
||||
import com.tangem.blockchain.common.Amount
|
||||
import com.tangem.blockchain.common.Approver
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.Token
|
||||
import com.tangem.blockchain.extensions.Result
|
||||
import com.tangem.data.tokens.utils.CryptoCurrencyFactory
|
||||
import com.tangem.datasource.api.oneinch.OneInchApi
|
||||
import com.tangem.datasource.api.oneinch.OneInchApiFactory
|
||||
|
|
@ -12,20 +16,21 @@ import com.tangem.domain.common.extensions.fromNetworkId
|
|||
import com.tangem.domain.common.util.derivationStyleProvider
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.Network
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.feature.swap.converters.ApproveConverter
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.feature.swap.converters.QuotesConverter
|
||||
import com.tangem.feature.swap.converters.SwapConverter
|
||||
import com.tangem.feature.swap.converters.TokensConverter
|
||||
import com.tangem.feature.swap.domain.SwapRepository
|
||||
import com.tangem.feature.swap.domain.models.data.AggregatedSwapDataModel
|
||||
import com.tangem.feature.swap.domain.models.domain.ApproveModel
|
||||
import com.tangem.feature.swap.domain.models.domain.Currency
|
||||
import com.tangem.feature.swap.domain.models.domain.QuoteModel
|
||||
import com.tangem.feature.swap.domain.models.domain.SwapDataModel
|
||||
import com.tangem.feature.swap.domain.models.mapErrors
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.math.BigDecimal
|
||||
import javax.inject.Inject
|
||||
import com.tangem.blockchain.common.Token as SdkToken
|
||||
|
||||
|
|
@ -35,12 +40,12 @@ internal class SwapRepositoryImpl @Inject constructor(
|
|||
private val oneInchErrorsHandler: OneInchErrorsHandler,
|
||||
private val coroutineDispatcher: CoroutineDispatcherProvider,
|
||||
private val configManager: ConfigManager,
|
||||
private val walletManagersFacade: WalletManagersFacade,
|
||||
) : SwapRepository {
|
||||
|
||||
private val tokensConverter = TokensConverter()
|
||||
private val quotesConverter = QuotesConverter()
|
||||
private val swapConverter = SwapConverter()
|
||||
private val approveConverter = ApproveConverter()
|
||||
|
||||
override suspend fun getRates(currencyId: String, tokenIds: List<String>): Map<String, Double> {
|
||||
// workaround cause backend do not return arbitrum and optimism rates
|
||||
|
|
@ -104,29 +109,6 @@ internal class SwapRepositoryImpl @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override suspend fun dataToApprove(networkId: String, tokenAddress: String, amount: String?): ApproveModel {
|
||||
return withContext(coroutineDispatcher.io) {
|
||||
approveConverter.convert(getOneInchApi(networkId).approveTransaction(tokenAddress, amount))
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun checkTokensSpendAllowance(
|
||||
networkId: String,
|
||||
tokenAddress: String,
|
||||
walletAddress: String,
|
||||
): AggregatedSwapDataModel<String> {
|
||||
return withContext(coroutineDispatcher.io) {
|
||||
try {
|
||||
val response = oneInchErrorsHandler.handleOneInchResponse(
|
||||
getOneInchApi(networkId).approveAllowance(tokenAddress, walletAddress),
|
||||
)
|
||||
AggregatedSwapDataModel(response.allowance)
|
||||
} catch (ex: OneIncResponseException) {
|
||||
AggregatedSwapDataModel(null, mapErrors(ex.data.description))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun prepareSwapTransaction(
|
||||
networkId: String,
|
||||
fromTokenAddress: String,
|
||||
|
|
@ -191,6 +173,73 @@ internal class SwapRepositoryImpl @Inject constructor(
|
|||
} as CryptoCurrency
|
||||
}
|
||||
|
||||
override suspend fun getAllowance(
|
||||
userWalletId: UserWalletId,
|
||||
networkId: String,
|
||||
derivationPath: String?,
|
||||
tokenDecimalCount: Int,
|
||||
tokenAddress: String,
|
||||
): BigDecimal {
|
||||
val blockchain = requireNotNull(Blockchain.fromNetworkId(networkId)) { "blockchain not found" }
|
||||
val walletManager = walletManagersFacade.getOrCreateWalletManager(
|
||||
userWalletId = userWalletId,
|
||||
blockchain = blockchain,
|
||||
derivationPath = derivationPath,
|
||||
)
|
||||
val spenderAddress = addressForTrust(networkId)
|
||||
|
||||
val result = (walletManager as? Approver)?.getAllowance(
|
||||
spenderAddress,
|
||||
Token(
|
||||
symbol = blockchain.currency,
|
||||
contractAddress = tokenAddress,
|
||||
decimals = tokenDecimalCount,
|
||||
),
|
||||
) ?: error("Cannot cast to Approver")
|
||||
|
||||
return when (result) {
|
||||
is Result.Success -> result.data
|
||||
is Result.Failure -> error(result.error)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getApproveData(
|
||||
userWalletId: UserWalletId,
|
||||
networkId: String,
|
||||
derivationPath: String?,
|
||||
currency: Currency,
|
||||
amount: BigDecimal?,
|
||||
): String {
|
||||
val blockchain =
|
||||
requireNotNull(Blockchain.fromNetworkId(networkId)) { "blockchain not found" }
|
||||
val walletManager = walletManagersFacade.getOrCreateWalletManager(
|
||||
userWalletId = userWalletId,
|
||||
blockchain = blockchain,
|
||||
derivationPath = derivationPath,
|
||||
)
|
||||
val spenderAddress = addressForTrust(networkId)
|
||||
|
||||
return (walletManager as? Approver)?.getApproveData(
|
||||
spenderAddress,
|
||||
amount?.let { convertToAmount(it, currency, blockchain) },
|
||||
) ?: error("Cannot cast to Approver")
|
||||
}
|
||||
|
||||
private fun convertToAmount(amount: BigDecimal, currency: Currency, blockchain: Blockchain): Amount {
|
||||
return when (currency) {
|
||||
is Currency.NativeToken -> {
|
||||
Amount(value = amount, blockchain = blockchain)
|
||||
}
|
||||
is Currency.NonNativeToken -> {
|
||||
Amount(
|
||||
currencySymbol = currency.symbol,
|
||||
value = amount,
|
||||
decimals = currency.decimalCount,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getOneInchApi(networkId: String): OneInchApi {
|
||||
return oneInchApiFactory.getApi(networkId)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +0,0 @@
|
|||
package com.tangem.feature.swap.converters
|
||||
|
||||
import com.tangem.datasource.api.oneinch.models.ApproveCalldataResponse
|
||||
import com.tangem.feature.swap.domain.models.domain.ApproveModel
|
||||
import com.tangem.utils.converter.Converter
|
||||
|
||||
class ApproveConverter : Converter<ApproveCalldataResponse, ApproveModel> {
|
||||
|
||||
override fun convert(value: ApproveCalldataResponse): ApproveModel {
|
||||
return ApproveModel(
|
||||
data = value.data,
|
||||
gasPrice = value.gasPrice,
|
||||
toAddress = value.toAddress,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ import com.tangem.datasource.api.oneinch.OneInchApiFactory
|
|||
import com.tangem.datasource.api.oneinch.OneInchErrorsHandler
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||
import com.tangem.datasource.config.ConfigManager
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
import com.tangem.feature.swap.SwapRepositoryImpl
|
||||
import com.tangem.feature.swap.domain.SwapRepository
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
|
|
@ -25,6 +26,7 @@ class SwapDataModule {
|
|||
oneInchErrorsHandler: OneInchErrorsHandler,
|
||||
coroutineDispatcher: CoroutineDispatcherProvider,
|
||||
configManager: ConfigManager,
|
||||
walletManagerFacade: WalletManagersFacade,
|
||||
): SwapRepository {
|
||||
return SwapRepositoryImpl(
|
||||
tangemTechApi = tangemTechApi,
|
||||
|
|
@ -32,6 +34,7 @@ class SwapDataModule {
|
|||
oneInchErrorsHandler = oneInchErrorsHandler,
|
||||
coroutineDispatcher = coroutineDispatcher,
|
||||
configManager = configManager,
|
||||
walletManagersFacade = walletManagerFacade,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -6,7 +6,6 @@ import com.tangem.domain.wallets.models.UserWallet
|
|||
import com.tangem.domain.wallets.usecase.GetSelectedWalletUseCase
|
||||
import com.tangem.feature.swap.domain.cache.SwapDataCache
|
||||
import com.tangem.feature.swap.domain.converters.SwapCurrencyConverter
|
||||
import com.tangem.feature.swap.domain.models.DataError
|
||||
import com.tangem.feature.swap.domain.models.SwapAmount
|
||||
import com.tangem.feature.swap.domain.models.domain.*
|
||||
import com.tangem.feature.swap.domain.models.domain.Currency
|
||||
|
|
@ -118,16 +117,20 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
|
||||
override suspend fun givePermissionToSwap(networkId: String, permissionOptions: PermissionOptions): TxState {
|
||||
val dataToSign = if (permissionOptions.approveType == SwapApproveType.UNLIMITED) {
|
||||
repository.dataToApprove(networkId, getTokenAddress(permissionOptions.fromToken)).data
|
||||
getApproveData(
|
||||
networkId = networkId,
|
||||
derivationPath = derivationPath,
|
||||
fromToken = permissionOptions.fromToken,
|
||||
)
|
||||
} else {
|
||||
permissionOptions.approveData.approveModel.data
|
||||
permissionOptions.approveData.approveData
|
||||
}
|
||||
val result = transactionManager.sendApproveTransaction(
|
||||
txData = ApproveTxData(
|
||||
networkId = networkId,
|
||||
feeAmount = permissionOptions.txFee.feeValue,
|
||||
gasLimit = permissionOptions.txFee.gasLimit,
|
||||
destinationAddress = permissionOptions.approveData.approveModel.toAddress,
|
||||
destinationAddress = getTokenAddress(permissionOptions.fromToken),
|
||||
dataToSign = dataToSign,
|
||||
),
|
||||
derivationPath = derivationPath,
|
||||
|
|
@ -164,7 +167,7 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
val amount = SwapAmount(amountDecimal, getTokenDecimals(fromToken))
|
||||
val fromTokenAddress = getTokenAddress(fromToken)
|
||||
val toTokenAddress = getTokenAddress(toToken)
|
||||
val isAllowedToSpend = isAllowedToSpend(networkId, fromTokenAddress, amount)
|
||||
val isAllowedToSpend = isAllowedToSpend(networkId, fromToken, amount)
|
||||
if (isAllowedToSpend && allowPermissionsHandler.isAddressAllowanceInProgress(fromTokenAddress)) {
|
||||
allowPermissionsHandler.removeAddressFromProgress(fromTokenAddress)
|
||||
transactionManager.updateWalletManager(networkId, derivationPath)
|
||||
|
|
@ -340,14 +343,23 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private suspend fun isAllowedToSpend(networkId: String, fromTokenAddress: String, amount: SwapAmount): Boolean {
|
||||
val allowance = repository.checkTokensSpendAllowance(
|
||||
networkId = networkId,
|
||||
tokenAddress = fromTokenAddress,
|
||||
walletAddress = userWalletManager.getWalletAddress(networkId, derivationPath),
|
||||
private suspend fun isAllowedToSpend(networkId: String, fromToken: Currency, amount: SwapAmount): Boolean {
|
||||
return getSelectedWalletUseCase().fold(
|
||||
ifRight = { userWallet ->
|
||||
val allowance = repository.getAllowance(
|
||||
userWallet.walletId,
|
||||
networkId,
|
||||
derivationPath,
|
||||
getTokenDecimals(fromToken),
|
||||
getTokenAddress(fromToken),
|
||||
)
|
||||
allowance >= amount.value
|
||||
},
|
||||
ifLeft = {
|
||||
Timber.e("Swap Error on isAllowedToSpend")
|
||||
false
|
||||
},
|
||||
)
|
||||
val allowanceAmount = allowance.dataModel?.toBigDecimalOrNull() ?: BigDecimal.ZERO
|
||||
return allowance.error == DataError.NoError && allowanceAmount >= amount.value.movePointRight(amount.decimals)
|
||||
}
|
||||
|
||||
private fun createEmptyAmountState(networkId: String, fromToken: Currency, toToken: Currency): SwapState {
|
||||
|
|
@ -558,18 +570,19 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
)
|
||||
}
|
||||
// setting up amount for approve with given amount for swap [SwapApproveType.Limited]
|
||||
val transactionData = repository.dataToApprove(
|
||||
val transactionData = getApproveData(
|
||||
networkId = networkId,
|
||||
tokenAddress = getTokenAddress(fromToken),
|
||||
amount = swapAmount.toStringWithRightOffset(),
|
||||
derivationPath = derivationPath,
|
||||
fromToken = fromToken,
|
||||
swapAmount = swapAmount,
|
||||
)
|
||||
val feeData = transactionManager.getFee(
|
||||
networkId = networkId,
|
||||
amountToSend = BigDecimal.ZERO,
|
||||
currencyToSend = userWalletManager.getNativeTokenForNetwork(networkId),
|
||||
destinationAddress = transactionData.toAddress,
|
||||
destinationAddress = getTokenAddress(fromToken),
|
||||
increaseBy = INCREASE_GAS_LIMIT_BY,
|
||||
data = transactionData.data,
|
||||
data = transactionData,
|
||||
derivationPath = derivationPath,
|
||||
)
|
||||
val feeState = proxyFeesToFeeState(networkId, feeData)
|
||||
|
|
@ -584,10 +597,10 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
currency = fromToken.symbol,
|
||||
amount = INFINITY_SYMBOL,
|
||||
walletAddress = getWalletAddress(networkId),
|
||||
spenderAddress = transactionData.toAddress,
|
||||
spenderAddress = getTokenAddress(fromToken),
|
||||
requestApproveData = RequestApproveStateData(
|
||||
fee = feeState,
|
||||
approveModel = transactionData,
|
||||
approveData = transactionData,
|
||||
),
|
||||
),
|
||||
preparedSwapConfigState = quotesLoadedState.preparedSwapConfigState.copy(
|
||||
|
|
@ -718,6 +731,29 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
return (BigDecimal.ONE - toTokenFiatValue.divide(fromTokenFiatValue, 2, RoundingMode.HALF_UP)).toFloat()
|
||||
}
|
||||
|
||||
private suspend fun getApproveData(
|
||||
networkId: String,
|
||||
derivationPath: String?,
|
||||
fromToken: Currency,
|
||||
swapAmount: SwapAmount? = null,
|
||||
): String {
|
||||
return getSelectedWalletUseCase().fold(
|
||||
ifRight = { userWallet ->
|
||||
repository.getApproveData(
|
||||
userWalletId = userWallet.walletId,
|
||||
networkId = networkId,
|
||||
derivationPath = derivationPath,
|
||||
currency = fromToken,
|
||||
amount = swapAmount?.value,
|
||||
)
|
||||
},
|
||||
ifLeft = {
|
||||
Timber.e("Swap Error on getApproveData")
|
||||
error("Swap Error on getApproveData")
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val DEFAULT_SLIPPAGE = 2
|
||||
private const val ZERO_BALANCE = "0"
|
||||
|
|
|
|||
|
|
@ -3,11 +3,12 @@ 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.domain.wallets.models.UserWalletId
|
||||
import com.tangem.feature.swap.domain.models.data.AggregatedSwapDataModel
|
||||
import com.tangem.feature.swap.domain.models.domain.ApproveModel
|
||||
import com.tangem.feature.swap.domain.models.domain.Currency
|
||||
import com.tangem.feature.swap.domain.models.domain.QuoteModel
|
||||
import com.tangem.feature.swap.domain.models.domain.SwapDataModel
|
||||
import java.math.BigDecimal
|
||||
|
||||
interface SwapRepository {
|
||||
|
||||
|
|
@ -29,28 +30,6 @@ interface SwapRepository {
|
|||
*/
|
||||
suspend fun addressForTrust(networkId: String): String
|
||||
|
||||
/**
|
||||
* Generate "data" for calling contract in order to allow 1inch spend funds
|
||||
*
|
||||
* @param tokenAddress token you want to exchange
|
||||
* @param amount number of tokens is allowed. By default infinite
|
||||
*/
|
||||
suspend fun dataToApprove(networkId: String, tokenAddress: String, amount: String? = null): ApproveModel
|
||||
|
||||
/**
|
||||
* Get the number of tokens that the 1inch router is allowed to spend
|
||||
*
|
||||
* @param tokenAddress Token address you want to exchange
|
||||
* @param walletAddress address for which you want to check
|
||||
*
|
||||
* @return amount of tokens allowed to spend
|
||||
*/
|
||||
suspend fun checkTokensSpendAllowance(
|
||||
networkId: String,
|
||||
tokenAddress: String,
|
||||
walletAddress: String,
|
||||
): AggregatedSwapDataModel<String>
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
suspend fun prepareSwapTransaction(
|
||||
networkId: String,
|
||||
|
|
@ -68,4 +47,22 @@ interface SwapRepository {
|
|||
fun getTangemFee(): Double
|
||||
|
||||
suspend fun getCryptoCurrency(userWallet: UserWallet, currency: Currency, network: Network): CryptoCurrency?
|
||||
|
||||
@Throws(IllegalStateException::class)
|
||||
suspend fun getAllowance(
|
||||
userWalletId: UserWalletId,
|
||||
networkId: String,
|
||||
derivationPath: String?,
|
||||
tokenDecimalCount: Int,
|
||||
tokenAddress: String,
|
||||
): BigDecimal
|
||||
|
||||
@Throws(IllegalStateException::class)
|
||||
suspend fun getApproveData(
|
||||
userWalletId: UserWalletId,
|
||||
networkId: String,
|
||||
derivationPath: String?,
|
||||
currency: Currency,
|
||||
amount: BigDecimal?,
|
||||
): String
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
package com.tangem.feature.swap.domain.models.cache
|
||||
|
||||
import com.tangem.feature.swap.domain.models.domain.ApproveModel
|
||||
import com.tangem.feature.swap.domain.models.domain.Currency
|
||||
import com.tangem.feature.swap.domain.models.domain.QuoteModel
|
||||
import com.tangem.feature.swap.domain.models.SwapAmount
|
||||
import com.tangem.feature.swap.domain.models.domain.SwapDataModel
|
||||
|
||||
data class SwapDataHolder(
|
||||
val quoteModel: QuoteModel? = null,
|
||||
val swapModel: SwapDataModel? = null,
|
||||
val approveTxModel: ApproveModel? = null,
|
||||
val amountToSwap: SwapAmount? = null,
|
||||
val networkId: String? = null,
|
||||
val exchangeCurrencies: ExchangeCurrencies? = null,
|
||||
)
|
||||
|
||||
data class ExchangeCurrencies(
|
||||
val fromCurrency: Currency? = null,
|
||||
val toCurrency: Currency? = null,
|
||||
)
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
package com.tangem.feature.swap.domain.models.domain
|
||||
|
||||
/**
|
||||
* Approve model
|
||||
*
|
||||
* @property data The encoded data to call the approve method on the swapped token contract
|
||||
* @property gasPrice Gas price for fast transaction processing
|
||||
* @property toAddress Token address that will be allowed to exchange through 1inch router
|
||||
*/
|
||||
data class ApproveModel(
|
||||
val data: String,
|
||||
val gasPrice: String,
|
||||
val toAddress: String,
|
||||
)
|
||||
|
|
@ -2,7 +2,6 @@ package com.tangem.feature.swap.domain.models.ui
|
|||
|
||||
import com.tangem.feature.swap.domain.models.DataError
|
||||
import com.tangem.feature.swap.domain.models.SwapAmount
|
||||
import com.tangem.feature.swap.domain.models.domain.ApproveModel
|
||||
import com.tangem.feature.swap.domain.models.domain.PreparedSwapConfigState
|
||||
import com.tangem.feature.swap.domain.models.domain.SwapDataModel
|
||||
import java.math.BigDecimal
|
||||
|
|
@ -59,7 +58,7 @@ data class TokenSwapInfo(
|
|||
|
||||
data class RequestApproveStateData(
|
||||
val fee: TxFeeState,
|
||||
val approveModel: ApproveModel,
|
||||
val approveData: String,
|
||||
)
|
||||
|
||||
data class SwapStateData(
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ okHttp-prettyLogging = "3.1.0"
|
|||
# endregion Other libraries
|
||||
|
||||
# region Tangem
|
||||
tangemBlockchainSdk = "develop-351"
|
||||
tangemBlockchainSdk = "develop-354"
|
||||
#tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds
|
||||
tangemCardSdk = "develop-300"
|
||||
#tangemCardSdk = "0.0.1" # Keep it! - used for local builds
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue