Updated on 2026-08-14
This commit is contained in:
parent
6dee2eeed7
commit
e7c330a5e1
16 changed files with 263 additions and 76 deletions
|
|
@ -12,7 +12,7 @@ import com.tangem.domain.common.TapWorkarounds.derivationStyle
|
|||
import com.tangem.domain.common.extensions.fromNetworkId
|
||||
import com.tangem.lib.crypto.DerivationManager
|
||||
import com.tangem.lib.crypto.models.Currency
|
||||
import com.tangem.lib.crypto.models.NonNativeToken
|
||||
import com.tangem.lib.crypto.models.Currency.NonNativeToken
|
||||
import com.tangem.operations.derivation.ExtendedPublicKeysMap
|
||||
import com.tangem.tap.DELAY_SDK_DIALOG_CLOSE
|
||||
import com.tangem.tap.common.extensions.dispatchDebugErrorNotification
|
||||
|
|
|
|||
|
|
@ -2,20 +2,24 @@ package com.tangem.tap.proxy
|
|||
|
||||
import com.google.firebase.crashlytics.FirebaseCrashlytics
|
||||
import com.tangem.Message
|
||||
import com.tangem.blockchain.blockchains.ethereum.EthereumTransactionExtras
|
||||
import com.tangem.blockchain.blockchains.ethereum.EthereumWalletManager
|
||||
import com.tangem.blockchain.common.Amount
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.BlockchainSdkError
|
||||
import com.tangem.blockchain.common.Token
|
||||
import com.tangem.blockchain.common.TransactionExtras
|
||||
import com.tangem.blockchain.common.TransactionSender
|
||||
import com.tangem.blockchain.common.TransactionSigner
|
||||
import com.tangem.blockchain.common.WalletManager
|
||||
import com.tangem.blockchain.extensions.Result
|
||||
import com.tangem.blockchain.extensions.SimpleResult
|
||||
import com.tangem.common.core.TangemSdkError
|
||||
import com.tangem.common.extensions.hexToBytes
|
||||
import com.tangem.domain.common.extensions.fromNetworkId
|
||||
import com.tangem.lib.crypto.TransactionManager
|
||||
import com.tangem.lib.crypto.models.Currency
|
||||
import com.tangem.lib.crypto.models.NativeToken
|
||||
import com.tangem.lib.crypto.models.NonNativeToken
|
||||
import com.tangem.lib.crypto.models.ProxyAmount
|
||||
import com.tangem.lib.crypto.models.transactions.SendTxResult
|
||||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
import com.tangem.tap.domain.TangemSigner
|
||||
|
|
@ -23,6 +27,7 @@ import com.tangem.tap.domain.tokens.models.BlockchainNetwork
|
|||
import com.tangem.tap.store
|
||||
import com.tangem.tap.tangemSdk
|
||||
import java.math.BigDecimal
|
||||
import java.math.BigInteger
|
||||
|
||||
class TransactionManagerImpl(
|
||||
private val appStateHolder: AppStateHolder,
|
||||
|
|
@ -39,22 +44,13 @@ class TransactionManagerImpl(
|
|||
): SendTxResult {
|
||||
val blockchain = requireNotNull(Blockchain.fromNetworkId(networkId)) { "blockchain not found" }
|
||||
val walletManager = getActualWalletManager(blockchain)
|
||||
val amount = when (currencyToSend) {
|
||||
is NativeToken -> {
|
||||
Amount(value = amountToSend, blockchain = blockchain)
|
||||
}
|
||||
is NonNativeToken -> {
|
||||
Amount(
|
||||
convertNonNativeToken(currencyToSend),
|
||||
amountToSend,
|
||||
)
|
||||
}
|
||||
}
|
||||
val amount = createAmount(amountToSend, currencyToSend, blockchain)
|
||||
|
||||
val txData = walletManager.createTransaction(
|
||||
amount = amount,
|
||||
fee = Amount(value = feeAmount, blockchain = blockchain),
|
||||
destination = destinationAddress,
|
||||
).copy(hash = dataToSign)
|
||||
).copy(hash = dataToSign, extras = createExtras(walletManager, feeAmount, dataToSign))
|
||||
|
||||
val signer = transactionSigner(walletManager)
|
||||
|
||||
|
|
@ -67,6 +63,33 @@ class TransactionManagerImpl(
|
|||
return handleSendResult(sendResult)
|
||||
}
|
||||
|
||||
@Throws(IllegalStateException::class)
|
||||
override suspend fun getFee(
|
||||
networkId: String,
|
||||
amountToSend: BigDecimal,
|
||||
currencyToSend: Currency,
|
||||
destinationAddress: String,
|
||||
): ProxyAmount {
|
||||
val blockchain = requireNotNull(Blockchain.fromNetworkId(networkId)) { "blockchain not found" }
|
||||
val walletManager = getActualWalletManager(blockchain)
|
||||
val fee = (walletManager as TransactionSender).getFee(
|
||||
amount = createAmount(amountToSend, currencyToSend, blockchain),
|
||||
destination = destinationAddress,
|
||||
)
|
||||
when (fee) {
|
||||
is Result.Success -> {
|
||||
return convertToProxyAmount(fee.data.firstOrNull() ?: error("no fee found"))
|
||||
}
|
||||
is Result.Failure -> {
|
||||
error(fee.error.message ?: fee.error.customMessage)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getNativeAddress(networkId: String): String {
|
||||
return "" //todo implement
|
||||
}
|
||||
|
||||
private fun handleSendResult(result: SimpleResult): SendTxResult {
|
||||
when (result) {
|
||||
is SimpleResult.Success -> {
|
||||
|
|
@ -121,7 +144,40 @@ class TransactionManagerImpl(
|
|||
}
|
||||
}
|
||||
|
||||
private fun convertNonNativeToken(token: NonNativeToken): Token {
|
||||
private fun createExtras(
|
||||
walletManager: WalletManager,
|
||||
feeAmount: BigDecimal,
|
||||
transactionHash: String,
|
||||
): TransactionExtras? {
|
||||
return when (walletManager) {
|
||||
is EthereumWalletManager -> {
|
||||
return EthereumTransactionExtras(
|
||||
data = transactionHash.removePrefix(HEX_PREFIX).hexToBytes(),
|
||||
gasLimit = BigInteger.valueOf(DEFAULT_GAS_LIMIT),
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun createAmount(
|
||||
amount: BigDecimal,
|
||||
currency: Currency,
|
||||
blockchain: Blockchain,
|
||||
): Amount {
|
||||
return when (currency) {
|
||||
is Currency.NativeToken -> {
|
||||
Amount(value = amount, blockchain = blockchain)
|
||||
}
|
||||
is Currency.NonNativeToken -> {
|
||||
Amount(convertNonNativeToken(currency), amount)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun convertNonNativeToken(token: Currency.NonNativeToken): Token {
|
||||
return Token(
|
||||
name = token.name,
|
||||
symbol = token.symbol,
|
||||
|
|
@ -130,4 +186,17 @@ class TransactionManagerImpl(
|
|||
id = token.id,
|
||||
)
|
||||
}
|
||||
|
||||
private fun convertToProxyAmount(amount: Amount): ProxyAmount {
|
||||
return ProxyAmount(
|
||||
currencySymbol = amount.currencySymbol,
|
||||
value = amount.value ?: BigDecimal.ZERO,
|
||||
decimals = amount.decimals,
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val HEX_PREFIX = "0x"
|
||||
private const val DEFAULT_GAS_LIMIT = 300000L
|
||||
}
|
||||
}
|
||||
|
|
@ -11,8 +11,8 @@ import com.tangem.domain.common.extensions.toNetworkId
|
|||
import com.tangem.domain.common.util.userWalletId
|
||||
import com.tangem.lib.crypto.UserWalletManager
|
||||
import com.tangem.lib.crypto.models.Currency
|
||||
import com.tangem.lib.crypto.models.NativeToken
|
||||
import com.tangem.lib.crypto.models.NonNativeToken
|
||||
import com.tangem.lib.crypto.models.Currency.NativeToken
|
||||
import com.tangem.lib.crypto.models.Currency.NonNativeToken
|
||||
import com.tangem.tap.domain.extensions.makeWalletManagerForApp
|
||||
import com.tangem.tap.domain.tokens.models.BlockchainNetwork
|
||||
import com.tangem.tap.features.wallet.redux.WalletAction
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import com.squareup.moshi.Json
|
|||
* @property toToken Destination token info
|
||||
* @property toTokenAmount Expected amount of destination token
|
||||
* @property fromTokenAmount Amount of source token
|
||||
* @property protocols Selected protocols in a path
|
||||
* @property estimatedGas gas fee
|
||||
*/
|
||||
data class QuoteResponse(
|
||||
|
|
@ -17,6 +16,5 @@ data class QuoteResponse(
|
|||
@Json(name = "toToken") val toToken: TokenOneInchDto,
|
||||
@Json(name = "toTokenAmount") val toTokenAmount: String,
|
||||
@Json(name = "fromTokenAmount") val fromTokenAmount: String,
|
||||
@Json(name = "protocols") val protocols: List<PathViewDto>,
|
||||
@Json(name = "estimatedGas") val estimatedGas: Int,
|
||||
)
|
||||
|
|
@ -2,8 +2,8 @@ package com.tangem.feature.referral.domain.converter
|
|||
|
||||
import com.tangem.feature.referral.domain.models.TokenData
|
||||
import com.tangem.lib.crypto.models.Currency
|
||||
import com.tangem.lib.crypto.models.NativeToken
|
||||
import com.tangem.lib.crypto.models.NonNativeToken
|
||||
import com.tangem.lib.crypto.models.Currency.NativeToken
|
||||
import com.tangem.lib.crypto.models.Currency.NonNativeToken
|
||||
import com.tangem.utils.converter.Converter
|
||||
|
||||
import javax.inject.Inject
|
||||
|
|
|
|||
|
|
@ -41,8 +41,7 @@ internal class SwapRepositoryImpl @Inject constructor(
|
|||
networkId: String, fromTokenAddress: String, toTokenAddress: String,
|
||||
amount:
|
||||
String,
|
||||
):
|
||||
AggregatedSwapDataModel<QuoteModel> {
|
||||
): AggregatedSwapDataModel<QuoteModel> {
|
||||
return withContext(coroutineDispatcher.io) {
|
||||
try {
|
||||
val response = oneInchErrorsHandler.handleOneInchResponse(
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.tangem.feature.swap.domain
|
|||
|
||||
import com.tangem.feature.swap.domain.models.data.Currency
|
||||
import com.tangem.feature.swap.domain.models.data.SwapState
|
||||
import java.math.BigDecimal
|
||||
|
||||
interface SwapInteractor {
|
||||
|
||||
|
|
@ -9,11 +10,13 @@ interface SwapInteractor {
|
|||
|
||||
suspend fun getTokenBalance(tokenId: String): String
|
||||
|
||||
suspend fun givePermissionToSwap(tokenAddress: String)
|
||||
suspend fun getFee(): BigDecimal
|
||||
|
||||
suspend fun givePermissionToSwap(tokenToApprove: Currency)
|
||||
|
||||
suspend fun findBestQuote(
|
||||
fromTokenAddress: String,
|
||||
toTokenAddress: String,
|
||||
fromToken: Currency,
|
||||
toToken: Currency,
|
||||
amount: String,
|
||||
): SwapState
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.feature.swap.domain
|
||||
|
||||
import com.tangem.feature.swap.domain.cache.SwapDataCache
|
||||
import com.tangem.feature.swap.domain.converters.CryptoCurrencyConverter
|
||||
import com.tangem.feature.swap.domain.models.data.Currency
|
||||
import com.tangem.feature.swap.domain.models.data.DataError
|
||||
import com.tangem.feature.swap.domain.models.data.SwapState
|
||||
|
|
@ -17,6 +18,8 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
private val cache: SwapDataCache,
|
||||
) : SwapInteractor {
|
||||
|
||||
private val cryptoCurrencyConverter = CryptoCurrencyConverter()
|
||||
|
||||
override suspend fun getTokensToSwap(networkId: String): List<Currency> {
|
||||
val availableTokens = cache.getAvailableTokens(networkId)
|
||||
return availableTokens.ifEmpty {
|
||||
|
|
@ -31,24 +34,48 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override suspend fun givePermissionToSwap(tokenAddress: String) {
|
||||
override suspend fun getFee(): BigDecimal {
|
||||
return transactionManager.getFee(
|
||||
networkId = cache.getNetworkId() ?: error("no networkId found, call getTokensToSwap first"),
|
||||
amountToSend = cache.getAmountToSwap() ?: error("no amount found, call findBestQuote first"),
|
||||
currencyToSend = cryptoCurrencyConverter.convert(
|
||||
cache.getExchangeCurrencies()?.fromCurrency ?: error(
|
||||
"no fromCurrency found, call findBestQuote first",
|
||||
),
|
||||
),
|
||||
destinationAddress = getTokenAddress(
|
||||
cache.getExchangeCurrencies()?.toCurrency ?: error(
|
||||
"no toCurrency found, call findBestQuote first",
|
||||
),
|
||||
),
|
||||
).value
|
||||
}
|
||||
|
||||
override suspend fun givePermissionToSwap(tokenToApprove: Currency) {
|
||||
cache.getNetworkId()?.let { networkId ->
|
||||
val oneInchAddress = repository.addressForTrust(networkId)
|
||||
val transactionData = repository.dataToApprove(networkId, tokenAddress)
|
||||
//todo for test
|
||||
// transactionManager.sendTransaction(
|
||||
// networkId = networkId,
|
||||
// amountToSend = BigDecimal.ZERO,
|
||||
// currencyToSend = ,
|
||||
// feeAmount = BigDecimal.ZERO,
|
||||
// destinationAddress = oneInchAddress,
|
||||
// dataToSign = transactionData.data
|
||||
// )
|
||||
if (tokenToApprove is Currency.NonNativeToken) {
|
||||
val estimatedGas =
|
||||
requireNotNull(cache.getLastQuote()?.estimatedGas) { "estimatedGas not found call findBestQuote" }
|
||||
val transactionData = repository.dataToApprove(networkId, tokenToApprove.contractAddress)
|
||||
val gasPrice = transactionData.gasPrice.toBigDecimalOrNull() ?: error("cannot parse gasPrice")
|
||||
val fee = gasPrice.multiply(estimatedGas.toBigDecimal()).movePointLeft(tokenToApprove.decimalCount)
|
||||
val result = transactionManager.sendTransaction(
|
||||
networkId = networkId,
|
||||
amountToSend = BigDecimal.ZERO,
|
||||
currencyToSend = cryptoCurrencyConverter.convert(tokenToApprove),
|
||||
feeAmount = fee,
|
||||
destinationAddress = transactionData.toAddress,
|
||||
dataToSign = transactionData.data,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun findBestQuote(fromTokenAddress: String, toTokenAddress: String, amount: String): SwapState {
|
||||
override suspend fun findBestQuote(fromToken: Currency, toToken: Currency, amount: String): SwapState {
|
||||
val networkId = cache.getNetworkId()
|
||||
val fromTokenAddress = getTokenAddress(fromToken)
|
||||
val toTokenAddress = getTokenAddress(toToken)
|
||||
val bigDecimalAmount = amount.toBigDecimalOrNull() ?: error("wrong amount format, use only digits")
|
||||
val isAllowedToSpend = if (networkId.isNullOrEmpty()) {
|
||||
error("no networkId found, please call getTokensToSwap first")
|
||||
} else {
|
||||
|
|
@ -68,7 +95,12 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
).let { quotes ->
|
||||
val quoteDataModel = quotes.dataModel
|
||||
if (quoteDataModel != null) {
|
||||
cache.cacheSwapParams(quoteDataModel.copy(isAllowedToSpend = isAllowedToSpend), amount)
|
||||
cache.cacheSwapParams(
|
||||
quoteModel = quoteDataModel.copy(isAllowedToSpend = isAllowedToSpend),
|
||||
amount = bigDecimalAmount,
|
||||
fromCurrency = fromToken,
|
||||
toCurrency = toToken,
|
||||
)
|
||||
return quoteDataModel
|
||||
} else {
|
||||
return SwapState.SwapError(quotes.error)
|
||||
|
|
@ -85,7 +117,7 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
networkId = networkId,
|
||||
fromTokenAddress = quoteModel.fromTokenAmount,
|
||||
toTokenAddress = quoteModel.toTokenAmount,
|
||||
amount = amountToSwap,
|
||||
amount = amountToSwap.toPlainString(),
|
||||
slippage = DEFAULT_SLIPPAGE,
|
||||
fromWalletAddress = getWalletAddress(networkId),
|
||||
).let {
|
||||
|
|
@ -109,6 +141,17 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
return userWalletManager.getWalletAddress(networkId)
|
||||
}
|
||||
|
||||
private fun getTokenAddress(currency: Currency): String {
|
||||
return when (currency) {
|
||||
is Currency.NativeToken -> {
|
||||
transactionManager.getNativeAddress(currency.networkId)
|
||||
}
|
||||
is Currency.NonNativeToken -> {
|
||||
currency.contractAddress
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//todo implement after merge referral
|
||||
private fun signTransactionData(transaction: TransactionModel) {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,18 @@
|
|||
package com.tangem.feature.swap.domain.cache
|
||||
|
||||
import com.tangem.feature.swap.domain.models.ExchangeCurrencies
|
||||
import com.tangem.feature.swap.domain.models.data.Currency
|
||||
import com.tangem.feature.swap.domain.models.data.SwapState.QuoteModel
|
||||
import java.math.BigDecimal
|
||||
|
||||
interface SwapDataCache {
|
||||
|
||||
fun cacheNetworkId(networkId: String)
|
||||
fun cacheSwapParams(quoteModel: QuoteModel, amount: String)
|
||||
fun cacheSwapParams(quoteModel: QuoteModel, amount: BigDecimal, fromCurrency: Currency, toCurrency: Currency)
|
||||
fun cacheAvailableToSwapTokens(networkId: String, tokens: List<Currency>)
|
||||
fun getAvailableTokens(networkId: String): List<Currency>
|
||||
fun getLastQuote(): QuoteModel?
|
||||
fun getAmountToSwap(): String?
|
||||
fun getAmountToSwap(): BigDecimal?
|
||||
fun getNetworkId(): String?
|
||||
fun getExchangeCurrencies(): ExchangeCurrencies?
|
||||
}
|
||||
|
|
@ -1,16 +1,35 @@
|
|||
package com.tangem.feature.swap.domain.cache
|
||||
|
||||
import com.tangem.feature.swap.domain.models.ExchangeCurrencies
|
||||
import com.tangem.feature.swap.domain.models.SwapDataHolder
|
||||
import com.tangem.feature.swap.domain.models.data.Currency
|
||||
import com.tangem.feature.swap.domain.models.data.SwapState.QuoteModel
|
||||
import java.math.BigDecimal
|
||||
|
||||
class SwapDataCacheImpl : SwapDataCache {
|
||||
|
||||
private var lastDataForSwap: SwapDataHolder = SwapDataHolder()
|
||||
private val availableTokensForNetwork: MutableMap<String, List<Currency>> = mutableMapOf()
|
||||
|
||||
override fun cacheSwapParams(quoteModel: QuoteModel, amount: String) {
|
||||
lastDataForSwap = lastDataForSwap.copy(quoteModel = quoteModel, amountToSwap = amount)
|
||||
override fun cacheSwapParams(
|
||||
quoteModel: QuoteModel,
|
||||
amount: BigDecimal,
|
||||
fromCurrency: Currency,
|
||||
toCurrency: Currency,
|
||||
) {
|
||||
lastDataForSwap =
|
||||
lastDataForSwap.copy(
|
||||
quoteModel = quoteModel,
|
||||
amountToSwap = amount,
|
||||
exchangeCurrencies = ExchangeCurrencies(
|
||||
fromCurrency = fromCurrency,
|
||||
toCurrency = toCurrency,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
override fun getExchangeCurrencies(): ExchangeCurrencies? {
|
||||
return lastDataForSwap.exchangeCurrencies
|
||||
}
|
||||
|
||||
override fun cacheAvailableToSwapTokens(networkId: String, tokens: List<Currency>) {
|
||||
|
|
@ -33,7 +52,7 @@ class SwapDataCacheImpl : SwapDataCache {
|
|||
return lastDataForSwap.quoteModel
|
||||
}
|
||||
|
||||
override fun getAmountToSwap(): String? {
|
||||
override fun getAmountToSwap(): BigDecimal? {
|
||||
return lastDataForSwap.amountToSwap
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package com.tangem.feature.swap.domain.converters
|
||||
|
||||
import com.tangem.feature.swap.domain.models.data.Currency
|
||||
import com.tangem.utils.converter.Converter
|
||||
|
||||
class CryptoCurrencyConverter : Converter<Currency, com.tangem.lib.crypto.models.Currency> {
|
||||
|
||||
override fun convert(value: Currency): com.tangem.lib.crypto.models.Currency {
|
||||
return when (value) {
|
||||
is Currency.NonNativeToken -> {
|
||||
com.tangem.lib.crypto.models.Currency.NonNativeToken(
|
||||
id = value.id,
|
||||
name = value.name,
|
||||
symbol = value.symbol,
|
||||
networkId = value.networkId,
|
||||
contractAddress = value.contractAddress,
|
||||
decimalCount = value.decimalCount,
|
||||
)
|
||||
}
|
||||
is Currency.NativeToken -> {
|
||||
com.tangem.lib.crypto.models.Currency.NativeToken(
|
||||
id = value.id,
|
||||
name = value.name,
|
||||
symbol = value.symbol,
|
||||
networkId = value.networkId,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,17 @@
|
|||
package com.tangem.feature.swap.domain.models
|
||||
|
||||
import com.tangem.feature.swap.domain.models.data.Currency
|
||||
import com.tangem.feature.swap.domain.models.data.SwapState.QuoteModel
|
||||
import java.math.BigDecimal
|
||||
|
||||
data class SwapDataHolder(
|
||||
val quoteModel:
|
||||
QuoteModel? = null,
|
||||
val amountToSwap: String? = null,
|
||||
val quoteModel: QuoteModel? = null,
|
||||
val amountToSwap: BigDecimal? = null,
|
||||
val networkId: String? = null,
|
||||
val exchangeCurrencies: ExchangeCurrencies? = null,
|
||||
)
|
||||
|
||||
data class ExchangeCurrencies(
|
||||
val fromCurrency: Currency? = null,
|
||||
val toCurrency: Currency? = null,
|
||||
)
|
||||
|
|
@ -61,23 +61,12 @@ internal class SwapViewModel @Inject constructor(
|
|||
val tokens = referralInteractor.getTokensToSwap("binance-smart-chain")
|
||||
val token = tokens[1]
|
||||
val token2 = tokens[2]
|
||||
if (token is Currency.NonNativeToken && token2 is Currency.NonNativeToken) {
|
||||
findBestQuotes(token.contractAddress, token2.contractAddress)
|
||||
}
|
||||
}.onFailure {
|
||||
Log.e("SwapViewModel", it.message ?: it.cause.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun findBestQuotes(fromTokenAddress: String, toTokenAddress: String) {
|
||||
referralInteractor.findBestQuote(
|
||||
fromTokenAddress,
|
||||
toTokenAddress,
|
||||
"1",
|
||||
)
|
||||
}
|
||||
|
||||
private fun createTestUiState(): SwapStateHolder {
|
||||
val sendCard = SwapCardData(
|
||||
type = TransactionCardType.SendCard("123", false),
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.lib.crypto
|
||||
|
||||
import com.tangem.lib.crypto.models.Currency
|
||||
import com.tangem.lib.crypto.models.ProxyAmount
|
||||
import com.tangem.lib.crypto.models.transactions.SendTxResult
|
||||
import java.math.BigDecimal
|
||||
|
||||
|
|
@ -14,4 +15,13 @@ interface TransactionManager {
|
|||
destinationAddress: String,
|
||||
dataToSign: String,
|
||||
): SendTxResult
|
||||
|
||||
suspend fun getFee(
|
||||
networkId: String,
|
||||
amountToSend: BigDecimal,
|
||||
currencyToSend: Currency,
|
||||
destinationAddress: String,
|
||||
): ProxyAmount
|
||||
|
||||
fun getNativeAddress(networkId: String): String
|
||||
}
|
||||
|
|
@ -9,20 +9,21 @@ sealed class Currency(
|
|||
open val name: String,
|
||||
open val symbol: String,
|
||||
open val networkId: String,
|
||||
)
|
||||
) {
|
||||
|
||||
data class NativeToken(
|
||||
override val id: String,
|
||||
override val name: String,
|
||||
override val symbol: String,
|
||||
override val networkId: String,
|
||||
) : Currency(id, name, symbol, networkId)
|
||||
data class NativeToken(
|
||||
override val id: String,
|
||||
override val name: String,
|
||||
override val symbol: String,
|
||||
override val networkId: String,
|
||||
) : Currency(id, name, symbol, networkId)
|
||||
|
||||
class NonNativeToken(
|
||||
override val id: String,
|
||||
override val name: String,
|
||||
override val symbol: String,
|
||||
override val networkId: String,
|
||||
val contractAddress: String,
|
||||
val decimalCount: Int,
|
||||
) : Currency(id, name, symbol, networkId)
|
||||
class NonNativeToken(
|
||||
override val id: String,
|
||||
override val name: String,
|
||||
override val symbol: String,
|
||||
override val networkId: String,
|
||||
val contractAddress: String,
|
||||
val decimalCount: Int,
|
||||
) : Currency(id, name, symbol, networkId)
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package com.tangem.lib.crypto.models
|
||||
|
||||
import java.math.BigDecimal
|
||||
|
||||
/**
|
||||
* Proxy amount is always has a Coin type
|
||||
*
|
||||
* @property currencySymbol
|
||||
* @property value amount in [BigDecimal]
|
||||
* @property decimals count for token
|
||||
*/
|
||||
data class ProxyAmount(
|
||||
val currencySymbol: String,
|
||||
var value: BigDecimal,
|
||||
val decimals: Int,
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue