From 7b69b597b6e1bc32c43ca673bd65414fd37b8c6e Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 30 May 2023 21:25:18 +0500 Subject: [PATCH 1/6] Updated on 2026-08-14 --- gradle/dependencies.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/dependencies.toml b/gradle/dependencies.toml index 2d33326ff2..52c9d2906f 100644 --- a/gradle/dependencies.toml +++ b/gradle/dependencies.toml @@ -73,7 +73,7 @@ reactiveNetwork = "3.0.8" # endregion Other libraries # region Tangem -tangemBlockchainSdk = "release-app_4.6-227" +tangemBlockchainSdk = "release-app_4.6-229" #tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds tangemCardSdk = "release-app_4.6-251" #tangemCardSdk = "0.0.1" # Keep it! - used for local builds From e182d88ebe3a89d544a352c2ac10ef73625f40e9 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 31 May 2023 10:35:16 +0300 Subject: [PATCH 2/6] Updated on 2026-08-14 --- app/src/main/AndroidManifest.xml | 48 +++++++++++--------------------- 1 file changed, 17 insertions(+), 31 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7e632399d0..b9fd68f4ee 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -49,6 +49,7 @@ android:launchMode="singleTop" android:screenOrientation="portrait" android:windowSoftInputMode="adjustResize"> + @@ -58,40 +59,25 @@ - - - - - - + + + - - - - + + + - + + + - - - + + + + + + + From 73ba136063c0a999855065cf18344f126d11ef82 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 31 May 2023 09:58:40 +0300 Subject: [PATCH 3/6] Updated on 2026-08-14 --- .../common/analytics/events/AnalyticsParam.kt | 50 ++++++++++++- .../tap/common/analytics/events/Basic.kt | 12 +++- .../send/redux/middlewares/SendMiddleware.kt | 72 ++++++++++--------- .../features/send/redux/states/FeeState.kt | 12 +++- .../tap/proxy/TransactionManagerImpl.kt | 70 +++++++++++------- .../feature/swap/domain/SwapInteractorImpl.kt | 46 +++++++----- .../domain/models/domain/SwapApproveType.kt | 7 ++ .../swap/domain/models/ui/SwapState.kt | 14 +++- .../feature/swap/ui/SwapScreenContent.kt | 4 ++ .../tangem/lib/crypto/TransactionManager.kt | 29 ++++---- .../tangem/lib/crypto/models/AnalyticsData.kt | 14 ++++ .../tangem/lib/crypto/models/ApproveTxData.kt | 20 ++++++ .../tangem/lib/crypto/models/SwapTxData.kt | 24 +++++++ 13 files changed, 274 insertions(+), 100 deletions(-) create mode 100644 libs/crypto/src/main/java/com/tangem/lib/crypto/models/AnalyticsData.kt create mode 100644 libs/crypto/src/main/java/com/tangem/lib/crypto/models/ApproveTxData.kt create mode 100644 libs/crypto/src/main/java/com/tangem/lib/crypto/models/SwapTxData.kt diff --git a/app/src/main/java/com/tangem/tap/common/analytics/events/AnalyticsParam.kt b/app/src/main/java/com/tangem/tap/common/analytics/events/AnalyticsParam.kt index 15c29ad5d0..7a788fd5c6 100644 --- a/app/src/main/java/com/tangem/tap/common/analytics/events/AnalyticsParam.kt +++ b/app/src/main/java/com/tangem/tap/common/analytics/events/AnalyticsParam.kt @@ -87,12 +87,54 @@ sealed class AnalyticsParam { } sealed class TxSentFrom(val value: String) { - object Send : TxSentFrom("Send") - object Swap : TxSentFrom("Swap") + data class Send( + override val blockchain: String, + override val token: String, + override val feeType: FeeType, + ) : TxSentFrom("Send"), TxData + + data class Swap( + override val blockchain: String, + override val token: String, + override val feeType: FeeType, + ) : TxSentFrom("Swap"), TxData + + data class Approve( + override val blockchain: String, + override val token: String, + override val feeType: FeeType, + val permissionType: String, + ) : TxSentFrom("Approve"), TxData + object WalletConnect : TxSentFrom("WalletConnect") object Sell : TxSentFrom("Sell") } + sealed interface TxData { + val blockchain: String + val token: String + val feeType: FeeType + } + + sealed class FeeType(val value: String) { + object Fixed : FeeType("Fixed") + object Min : FeeType("Min") + object Normal : FeeType("Normal") + object Max : FeeType("Max") + + companion object { + fun fromString(feeType: String): FeeType { + return when (feeType) { + Min.value -> Min + Normal.value -> Normal + Max.value -> Max + Fixed.value -> Fixed + else -> Fixed + } + } + } + } + sealed class WalletCreationType(val value: String) { object PrivateKey : WalletCreationType("Private key") object NewSeed : WalletCreationType("New seed") @@ -100,9 +142,13 @@ sealed class AnalyticsParam { } companion object Key { + const val BLOCKCHAIN = "blockchain" + const val TOKEN = "Token" const val SOURCE = "Source" const val BALANCE = "Balance" const val BATCH = "Batch" + const val FEE_TYPE = "Fee Type" + const val PERMISSION_TYPE = "Permission Type" const val PRODUCT_TYPE = "Product Type" const val FIRMWARE = "Firmware" const val CURRENCY = "Currency" diff --git a/app/src/main/java/com/tangem/tap/common/analytics/events/Basic.kt b/app/src/main/java/com/tangem/tap/common/analytics/events/Basic.kt index 4f63bd4961..d9b029fcae 100644 --- a/app/src/main/java/com/tangem/tap/common/analytics/events/Basic.kt +++ b/app/src/main/java/com/tangem/tap/common/analytics/events/Basic.kt @@ -51,7 +51,17 @@ sealed class Basic( class TransactionSent(sentFrom: AnalyticsParam.TxSentFrom) : Basic( event = "Transaction sent", - params = mapOf(AnalyticsParam.SOURCE to sentFrom.value), + params = buildMap { + this[AnalyticsParam.SOURCE] = sentFrom.value + if (sentFrom is AnalyticsParam.TxData) { + this[AnalyticsParam.BLOCKCHAIN] = sentFrom.blockchain + this[AnalyticsParam.TOKEN] = sentFrom.token + this[AnalyticsParam.FEE_TYPE] = sentFrom.feeType.value + } + if (sentFrom is AnalyticsParam.TxSentFrom.Approve) { + this[AnalyticsParam.PERMISSION_TYPE] = sentFrom.permissionType + } + }, ) class ScanError(error: Throwable) : Basic( diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt index 2d22340b26..dbc8be67c1 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt @@ -7,28 +7,20 @@ import com.tangem.blockchain.blockchains.polkadot.ExistentialDepositProvider import com.tangem.blockchain.blockchains.stellar.StellarTransactionExtras import com.tangem.blockchain.blockchains.ton.TonTransactionExtras import com.tangem.blockchain.blockchains.xrp.XrpTransactionBuilder -import com.tangem.blockchain.common.Amount -import com.tangem.blockchain.common.BlockchainSdkError -import com.tangem.blockchain.common.TransactionError -import com.tangem.blockchain.common.TransactionSender -import com.tangem.blockchain.common.WalletManager +import com.tangem.blockchain.common.* import com.tangem.blockchain.extensions.SimpleResult import com.tangem.common.core.TangemSdkError import com.tangem.common.extensions.guard import com.tangem.common.services.Result import com.tangem.core.analytics.Analytics -import com.tangem.domain.models.scan.CardDTO import com.tangem.domain.common.TapWorkarounds.isStart2Coin import com.tangem.domain.common.extensions.withMainContext -import com.tangem.tap.DELAY_SDK_DIALOG_CLOSE +import com.tangem.domain.models.scan.CardDTO +import com.tangem.tap.* import com.tangem.tap.common.analytics.events.AnalyticsParam import com.tangem.tap.common.analytics.events.Basic import com.tangem.tap.common.analytics.events.Token -import com.tangem.tap.common.extensions.dispatchDialogShow -import com.tangem.tap.common.extensions.dispatchErrorNotification -import com.tangem.tap.common.extensions.dispatchOnMain -import com.tangem.tap.common.extensions.safeUpdate -import com.tangem.tap.common.extensions.stripZeroPlainString +import com.tangem.tap.common.extensions.* import com.tangem.tap.common.redux.AppDialog import com.tangem.tap.common.redux.AppState import com.tangem.tap.common.redux.global.GlobalAction @@ -39,25 +31,11 @@ import com.tangem.tap.domain.configurable.warningMessage.WarningMessage import com.tangem.tap.domain.extensions.minimalAmount import com.tangem.tap.features.demo.DemoTransactionSender import com.tangem.tap.features.demo.isDemoCard -import com.tangem.tap.features.send.redux.AddressPayIdActionUi -import com.tangem.tap.features.send.redux.AddressPayIdVerifyAction -import com.tangem.tap.features.send.redux.AmountAction -import com.tangem.tap.features.send.redux.AmountActionUi +import com.tangem.tap.features.send.redux.* import com.tangem.tap.features.send.redux.FeeAction.RequestFee -import com.tangem.tap.features.send.redux.PrepareSendScreen -import com.tangem.tap.features.send.redux.SendAction -import com.tangem.tap.features.send.redux.SendActionUi -import com.tangem.tap.features.send.redux.states.ButtonState -import com.tangem.tap.features.send.redux.states.ExternalTransactionData -import com.tangem.tap.features.send.redux.states.MainCurrencyType -import com.tangem.tap.features.send.redux.states.TransactionExtrasState +import com.tangem.tap.features.send.redux.states.* import com.tangem.tap.features.wallet.models.Currency import com.tangem.tap.features.wallet.redux.WalletAction -import com.tangem.tap.scope -import com.tangem.tap.store -import com.tangem.tap.tangemSdk -import com.tangem.tap.userWalletsListManager -import com.tangem.tap.walletCurrenciesManager import com.tangem.wallet.R import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay @@ -65,7 +43,7 @@ import kotlinx.coroutines.launch import org.rekotlin.Action import org.rekotlin.Middleware import timber.log.Timber -import java.util.* +import java.util.EnumSet /** [REDACTED_AUTHOR] @@ -134,9 +112,16 @@ private fun verifyAndSendTransaction( }, sendAllCallback = { sendTransaction( - action, walletManager, amountToSend, feeAmount, destinationAddress, - sendState.transactionExtrasState, card, sendState.externalTransactionData, - dispatch, + action = action, + walletManager = walletManager, + amountToSend = amountToSend, + feeAmount = feeAmount, + feeType = sendState.feeState.selectedFeeType, + destinationAddress = destinationAddress, + transactionExtras = sendState.transactionExtrasState, + card = card, + externalTransactionData = sendState.externalTransactionData, + dispatch = dispatch, ) }, reduceAmount, @@ -145,8 +130,16 @@ private fun verifyAndSendTransaction( } else -> { sendTransaction( - action, walletManager, amountToSend, feeAmount, destinationAddress, - sendState.transactionExtrasState, card, sendState.externalTransactionData, dispatch, + action = action, + walletManager = walletManager, + amountToSend = amountToSend, + feeAmount = feeAmount, + feeType = sendState.feeState.selectedFeeType, + destinationAddress = destinationAddress, + transactionExtras = sendState.transactionExtrasState, + card = card, + externalTransactionData = sendState.externalTransactionData, + dispatch = dispatch, ) } } @@ -158,6 +151,7 @@ private fun sendTransaction( walletManager: WalletManager, amountToSend: Amount, feeAmount: Amount, + feeType: FeeType, destinationAddress: String, transactionExtras: TransactionExtrasState, card: CardDTO, @@ -253,7 +247,15 @@ private fun sendTransaction( Analytics.send(Basic.TransactionSent(AnalyticsParam.TxSentFrom.Sell)) dispatch(WalletAction.TradeCryptoAction.FinishSelling(externalTransactionData.transactionId)) } else { - Analytics.send(Basic.TransactionSent(AnalyticsParam.TxSentFrom.Send)) + Analytics.send( + Basic.TransactionSent( + sentFrom = AnalyticsParam.TxSentFrom.Send( + blockchain = walletManager.wallet.blockchain.fullName, + token = amountToSend.currencySymbol, + feeType = feeType.convertToAnalyticsFeeType(), + ), + ), + ) dispatch(NavigationAction.PopBackTo()) } scope.launch(Dispatchers.IO) { diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/states/FeeState.kt b/app/src/main/java/com/tangem/tap/features/send/redux/states/FeeState.kt index e9c9472bb4..65067fc0f8 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/states/FeeState.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/states/FeeState.kt @@ -1,6 +1,7 @@ package com.tangem.tap.features.send.redux.states import com.tangem.blockchain.common.Amount +import com.tangem.tap.common.analytics.events.AnalyticsParam import com.tangem.tap.features.wallet.redux.ProgressState import java.math.BigDecimal @@ -8,7 +9,16 @@ import java.math.BigDecimal [REDACTED_AUTHOR] */ enum class FeeType { - SINGLE, LOW, NORMAL, PRIORITY + SINGLE, LOW, NORMAL, PRIORITY; +} + +fun FeeType.convertToAnalyticsFeeType(): AnalyticsParam.FeeType { + return when (this) { + FeeType.SINGLE -> AnalyticsParam.FeeType.Fixed + FeeType.LOW -> AnalyticsParam.FeeType.Min + FeeType.NORMAL -> AnalyticsParam.FeeType.Normal + FeeType.PRIORITY -> AnalyticsParam.FeeType.Max + } } data class FeeState( diff --git a/app/src/main/java/com/tangem/tap/proxy/TransactionManagerImpl.kt b/app/src/main/java/com/tangem/tap/proxy/TransactionManagerImpl.kt index dabd3c53ec..216203fce9 100644 --- a/app/src/main/java/com/tangem/tap/proxy/TransactionManagerImpl.kt +++ b/app/src/main/java/com/tangem/tap/proxy/TransactionManagerImpl.kt @@ -34,14 +34,11 @@ class TransactionManagerImpl( ) : TransactionManager { override suspend fun sendApproveTransaction( - networkId: String, - feeAmount: BigDecimal, - gasLimit: Int, - destinationAddress: String, - dataToSign: String, + txData: ApproveTxData, derivationPath: String?, + analyticsData: AnalyticsData, ): SendTxResult { - val blockchain = requireNotNull(Blockchain.fromNetworkId(networkId)) { "blockchain not found" } + val blockchain = requireNotNull(Blockchain.fromNetworkId(txData.networkId)) { "blockchain not found" } val walletManager = getActualWalletManager(blockchain, derivationPath) walletManager.update() val amount = Amount(value = BigDecimal.ZERO, blockchain = blockchain) @@ -49,40 +46,55 @@ class TransactionManagerImpl( walletManager = walletManager, amount = amount, blockchain = blockchain, - feeAmount = feeAmount, - gasLimit = gasLimit, - destinationAddress = destinationAddress, - dataToSign = dataToSign, + feeAmount = txData.feeAmount, + gasLimit = txData.gasLimit, + destinationAddress = txData.destinationAddress, + dataToSign = txData.dataToSign, + successEvent = AnalyticsParam.TxSentFrom.Approve( + blockchain = blockchain.fullName, + token = analyticsData.tokenSymbol, + feeType = AnalyticsParam.FeeType.fromString(analyticsData.feeType), + permissionType = analyticsData.permissionType ?: "", + ), ) } override suspend fun sendTransaction( - networkId: String, - amountToSend: BigDecimal, - feeAmount: BigDecimal, - gasLimit: Int, - destinationAddress: String, - dataToSign: String, + txData: SwapTxData, isSwap: Boolean, - currencyToSend: Currency, derivationPath: String?, + analyticsData: AnalyticsData, ): SendTxResult { - val blockchain = requireNotNull(Blockchain.fromNetworkId(networkId)) { "blockchain not found" } + val blockchain = requireNotNull(Blockchain.fromNetworkId(txData.networkId)) { "blockchain not found" } val walletManager = getActualWalletManager(blockchain, derivationPath) walletManager.update() val amount = if (isSwap) { - createAmountForSwap(amountToSend, currencyToSend, blockchain) + createAmountForSwap(txData.amountToSend, txData.currencyToSend, blockchain) } else { - createAmount(amountToSend, currencyToSend, blockchain) + createAmount(txData.amountToSend, txData.currencyToSend, blockchain) + } + val successEvent = if (isSwap) { + AnalyticsParam.TxSentFrom.Swap( + blockchain = blockchain.fullName, + token = analyticsData.tokenSymbol, + feeType = AnalyticsParam.FeeType.fromString(analyticsData.feeType), + ) + } else { + AnalyticsParam.TxSentFrom.Send( + blockchain = blockchain.fullName, + token = analyticsData.tokenSymbol, + feeType = AnalyticsParam.FeeType.fromString(analyticsData.feeType), + ) } return sendTransactionInternal( walletManager = walletManager, amount = amount, blockchain = blockchain, - feeAmount = feeAmount, - gasLimit = gasLimit, - destinationAddress = destinationAddress, - dataToSign = dataToSign, + feeAmount = txData.feeAmount, + gasLimit = txData.gasLimit, + destinationAddress = txData.destinationAddress, + dataToSign = txData.dataToSign, + successEvent = successEvent, ) } @@ -95,6 +107,7 @@ class TransactionManagerImpl( gasLimit: Int, destinationAddress: String, dataToSign: String, + successEvent: AnalyticsParam.TxSentFrom, ): SendTxResult { val txData = walletManager.createTransaction( amount = amount, @@ -110,7 +123,10 @@ class TransactionManagerImpl( FirebaseCrashlytics.getInstance().recordException(ex) return SendTxResult.UnknownError(ex) } - return handleSendResult(sendResult) + return handleSendResult( + result = sendResult, + successEvent = successEvent, + ) } override fun getExplorerTransactionLink(networkId: String, txAddress: String): String { @@ -319,10 +335,10 @@ class TransactionManagerImpl( } } - private fun handleSendResult(result: SimpleResult): SendTxResult { + private fun handleSendResult(result: SimpleResult, successEvent: AnalyticsParam.TxSentFrom): SendTxResult { when (result) { is SimpleResult.Success -> { - analytics.send(Basic.TransactionSent(AnalyticsParam.TxSentFrom.Swap)) + analytics.send(Basic.TransactionSent(sentFrom = successEvent)) return SendTxResult.Success } is SimpleResult.Failure -> { 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 835ebdf273..25a3e74cf3 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 @@ -4,16 +4,13 @@ import com.tangem.feature.swap.domain.cache.SwapDataCache import com.tangem.feature.swap.domain.converters.CryptoCurrencyConverter 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 -import com.tangem.feature.swap.domain.models.domain.PermissionOptions -import com.tangem.feature.swap.domain.models.domain.PreparedSwapConfigState -import com.tangem.feature.swap.domain.models.domain.SwapApproveType import com.tangem.feature.swap.domain.models.toStringWithRightOffset import com.tangem.feature.swap.domain.models.ui.* import com.tangem.lib.crypto.TransactionManager import com.tangem.lib.crypto.UserWalletManager -import com.tangem.lib.crypto.models.ProxyFees -import com.tangem.lib.crypto.models.ProxyFiatCurrency +import com.tangem.lib.crypto.models.* import com.tangem.lib.crypto.models.transactions.SendTxResult import com.tangem.utils.toFiatString import java.math.BigDecimal @@ -115,12 +112,19 @@ internal class SwapInteractorImpl @Inject constructor( permissionOptions.approveData.approveModel.data } val result = transactionManager.sendApproveTransaction( - networkId = networkId, - feeAmount = permissionOptions.txFee.feeValue, - gasLimit = permissionOptions.txFee.gasLimit, - destinationAddress = permissionOptions.approveData.approveModel.toAddress, - dataToSign = dataToSign, + txData = ApproveTxData( + networkId = networkId, + feeAmount = permissionOptions.txFee.feeValue, + gasLimit = permissionOptions.txFee.gasLimit, + destinationAddress = permissionOptions.approveData.approveModel.toAddress, + dataToSign = dataToSign, + ), derivationPath = derivationPath, + analyticsData = AnalyticsData( + feeType = permissionOptions.txFee.feeType.getNameForAnalytics(), + tokenSymbol = permissionOptions.fromToken.symbol, + permissionType = permissionOptions.approveType.getNameForAnalytics(), + ), ) return when (result) { is SendTxResult.Success -> { @@ -188,15 +192,21 @@ internal class SwapInteractorImpl @Inject constructor( ): TxState { val amount = requireNotNull(toBigDecimalOrNull(amountToSwap)) { "wrong amount format, use only digits" } val result = transactionManager.sendTransaction( - networkId = networkId, - amountToSend = amount, - currencyToSend = cryptoCurrencyConverter.convert(currencyToSend), - feeAmount = fee.feeValue, - gasLimit = fee.gasLimit, - destinationAddress = swapStateData.swapModel.transaction.toWalletAddress, - dataToSign = swapStateData.swapModel.transaction.data, + txData = SwapTxData( + networkId = networkId, + amountToSend = amount, + currencyToSend = cryptoCurrencyConverter.convert(currencyToSend), + feeAmount = fee.feeValue, + gasLimit = fee.gasLimit, + destinationAddress = swapStateData.swapModel.transaction.toWalletAddress, + dataToSign = swapStateData.swapModel.transaction.data, + ), isSwap = true, derivationPath = derivationPath, + analyticsData = AnalyticsData( + feeType = fee.feeType.getNameForAnalytics(), + tokenSymbol = currencyToSend.symbol, + ), ) return when (result) { is SendTxResult.Success -> { @@ -587,12 +597,14 @@ internal class SwapInteractorImpl @Inject constructor( gasLimit = normalFeeGas, feeFiatFormatted = normalFiatFee, feeCryptoFormatted = normalCryptoFee, + feeType = FeeType.NORMAL, ), priorityFee = TxFee( feeValue = priorityFeeValue, gasLimit = priorityFeeGas, feeFiatFormatted = priorityFiatFee, feeCryptoFormatted = priorityCryptoFee, + feeType = FeeType.PRIORITY, ), ) } diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/domain/SwapApproveType.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/domain/SwapApproveType.kt index 8690e83395..21ded70713 100644 --- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/domain/SwapApproveType.kt +++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/domain/SwapApproveType.kt @@ -2,4 +2,11 @@ package com.tangem.feature.swap.domain.models.domain enum class SwapApproveType { LIMITED, UNLIMITED +} + +fun SwapApproveType.getNameForAnalytics(): String { + return when (this) { + SwapApproveType.LIMITED -> "Transaction" + SwapApproveType.UNLIMITED -> "Unlimited" + } } \ No newline at end of file diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/ui/SwapState.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/ui/SwapState.kt index 8e4258d548..d2b760740e 100644 --- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/ui/SwapState.kt +++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/ui/SwapState.kt @@ -77,4 +77,16 @@ data class TxFee( val gasLimit: Int, val feeFiatFormatted: String, val feeCryptoFormatted: String, -) \ No newline at end of file + val feeType: FeeType, +) + +enum class FeeType { + NORMAL, PRIORITY +} + +fun FeeType.getNameForAnalytics(): String { + return when (this) { + FeeType.NORMAL -> "Normal" + FeeType.PRIORITY -> "Max" + } +} \ 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 b7a127af0b..ae0bfbff26 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 @@ -25,6 +25,7 @@ import com.tangem.core.ui.extensions.TextReference import com.tangem.core.ui.extensions.getActiveIconRes import com.tangem.core.ui.extensions.getActiveIconResByCoinId import com.tangem.core.ui.res.TangemTheme +import com.tangem.feature.swap.domain.models.ui.FeeType import com.tangem.feature.swap.domain.models.ui.TxFee import com.tangem.feature.swap.models.* import com.tangem.feature.swap.presentation.R @@ -394,6 +395,7 @@ val stateSelectable = SelectableItemsState( gasLimit = 0, feeFiatFormatted = "", feeCryptoFormatted = "", + feeType = FeeType.NORMAL, ), ), items = listOf( @@ -407,6 +409,7 @@ val stateSelectable = SelectableItemsState( gasLimit = 0, feeFiatFormatted = "", feeCryptoFormatted = "", + feeType = FeeType.NORMAL, ), ), Item( @@ -419,6 +422,7 @@ val stateSelectable = SelectableItemsState( gasLimit = 0, feeFiatFormatted = "", feeCryptoFormatted = "", + feeType = FeeType.NORMAL, ), ), ).toImmutableList(), diff --git a/libs/crypto/src/main/java/com/tangem/lib/crypto/TransactionManager.kt b/libs/crypto/src/main/java/com/tangem/lib/crypto/TransactionManager.kt index 8c7e7412f0..5a915b109e 100644 --- a/libs/crypto/src/main/java/com/tangem/lib/crypto/TransactionManager.kt +++ b/libs/crypto/src/main/java/com/tangem/lib/crypto/TransactionManager.kt @@ -1,8 +1,6 @@ package com.tangem.lib.crypto -import com.tangem.lib.crypto.models.Currency -import com.tangem.lib.crypto.models.ProxyFees -import com.tangem.lib.crypto.models.ProxyNetworkInfo +import com.tangem.lib.crypto.models.* import com.tangem.lib.crypto.models.transactions.SendTxResult import java.math.BigDecimal @@ -11,26 +9,25 @@ interface TransactionManager { @Suppress("LongParameterList") @Throws(IllegalStateException::class) suspend fun sendApproveTransaction( - networkId: String, - feeAmount: BigDecimal, - gasLimit: Int, - destinationAddress: String, - dataToSign: String, + txData: ApproveTxData, derivationPath: String?, + analyticsData: AnalyticsData, ): SendTxResult - @Suppress("LongParameterList") + /** + * Send transaction + * + * @param txData data to build a tx + * @param derivationPath for select right walletManager + * @param analyticsData data for send analytics event + * @return result of transaction + */ @Throws(IllegalStateException::class) suspend fun sendTransaction( - networkId: String, - amountToSend: BigDecimal, - feeAmount: BigDecimal, - gasLimit: Int, - destinationAddress: String, - dataToSign: String, + txData: SwapTxData, isSwap: Boolean, - currencyToSend: Currency, derivationPath: String?, + analyticsData: AnalyticsData, ): SendTxResult /** diff --git a/libs/crypto/src/main/java/com/tangem/lib/crypto/models/AnalyticsData.kt b/libs/crypto/src/main/java/com/tangem/lib/crypto/models/AnalyticsData.kt new file mode 100644 index 0000000000..71a0845c8d --- /dev/null +++ b/libs/crypto/src/main/java/com/tangem/lib/crypto/models/AnalyticsData.kt @@ -0,0 +1,14 @@ +package com.tangem.lib.crypto.models + +/** + * Analytics data for send events in analytics engine + * + * @property feeType type of fee (min,max,normal) + * @property tokenSymbol symbol + * @property permissionType optional parameter used for type tx approve + */ +data class AnalyticsData( + val feeType: String, + val tokenSymbol: String, + val permissionType: String? = null, +) \ No newline at end of file diff --git a/libs/crypto/src/main/java/com/tangem/lib/crypto/models/ApproveTxData.kt b/libs/crypto/src/main/java/com/tangem/lib/crypto/models/ApproveTxData.kt new file mode 100644 index 0000000000..f2bfab34e3 --- /dev/null +++ b/libs/crypto/src/main/java/com/tangem/lib/crypto/models/ApproveTxData.kt @@ -0,0 +1,20 @@ +package com.tangem.lib.crypto.models + +import java.math.BigDecimal + +/** + * Tx data for create and make approve transaction + * + * @property networkId id of network + * @property feeAmount amount of fee + * @property gasLimit gasLimit for given tx + * @property destinationAddress address to send tx + * @property dataToSign data to sing with signer + */ +data class ApproveTxData( + val networkId: String, + val feeAmount: BigDecimal, + val gasLimit: Int, + val destinationAddress: String, + val dataToSign: String, +) \ No newline at end of file diff --git a/libs/crypto/src/main/java/com/tangem/lib/crypto/models/SwapTxData.kt b/libs/crypto/src/main/java/com/tangem/lib/crypto/models/SwapTxData.kt new file mode 100644 index 0000000000..723169c990 --- /dev/null +++ b/libs/crypto/src/main/java/com/tangem/lib/crypto/models/SwapTxData.kt @@ -0,0 +1,24 @@ +package com.tangem.lib.crypto.models + +import java.math.BigDecimal + +/** + * Tx data for create and make transaction + * + * @property networkId id of network + * @property feeAmount amount of fee + * @property gasLimit gasLimit for given tx + * @property destinationAddress address to send tx + * @property dataToSign data to sing with signer + * @property amountToSend amount of tx + * @property currencyToSend currency for tx + */ +data class SwapTxData( + val networkId: String, + val feeAmount: BigDecimal, + val gasLimit: Int, + val destinationAddress: String, + val dataToSign: String, + val amountToSend: BigDecimal, + val currencyToSend: Currency, +) \ No newline at end of file From 83333659d510a58d63a6b5812f691fee592e914a Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 31 May 2023 19:36:27 +0500 Subject: [PATCH 4/6] Updated on 2026-08-14 --- .../connection/RealInternetConnectionManager.kt | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/core/datasource/src/main/java/com/tangem/datasource/connection/RealInternetConnectionManager.kt b/core/datasource/src/main/java/com/tangem/datasource/connection/RealInternetConnectionManager.kt index 669dc8ed20..935ec93a24 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/connection/RealInternetConnectionManager.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/connection/RealInternetConnectionManager.kt @@ -1,6 +1,7 @@ package com.tangem.datasource.connection import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork +import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings import com.tangem.utils.coroutines.FeatureCoroutineExceptionHandler import io.reactivex.BackpressureStrategy import kotlinx.coroutines.CoroutineScope @@ -11,6 +12,8 @@ import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.reactive.asFlow +private const val PING_INTERVAL = 5_000 + internal class RealInternetConnectionManager : NetworkConnectionManager { private val scope = @@ -19,10 +22,14 @@ internal class RealInternetConnectionManager : NetworkConnectionManager { ) override val isOnlineFlow: StateFlow = ReactiveNetwork - .observeInternetConnectivity() + .observeInternetConnectivity( + InternetObservingSettings.builder() + .interval(PING_INTERVAL) + .build() + ) .toFlowable(BackpressureStrategy.LATEST) .asFlow() - .stateIn(scope, SharingStarted.Eagerly, initialValue = false) + .stateIn(scope, SharingStarted.Lazily, initialValue = false) override val isOnline: Boolean get() = isOnlineFlow.value From 9865c83f37c0338e61b0d7d67906200bd83327af Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 31 May 2023 14:28:57 +0300 Subject: [PATCH 5/6] Updated on 2026-08-14 --- .../java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 25a3e74cf3..b9a301369f 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 @@ -682,7 +682,7 @@ internal class SwapInteractorImpl @Inject constructor( private const val DEFAULT_SLIPPAGE = 2 private const val ZERO_BALANCE = "0" private const val DEFAULT_BLOCKCHAIN_INCH_ADDRESS = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE" - private const val INCREASE_FEE_TO_CHECK_ENOUGH_PERCENT = 1.4 + private const val INCREASE_FEE_TO_CHECK_ENOUGH_PERCENT = 1.0 // if need to increase fee when check isEnough private const val INCREASE_GAS_LIMIT_BY = 125 // 25% private const val USDT_SYMBOL = "USDT" private const val USDC_SYMBOL = "USDC" From e4502114a318d6bf1629c2c5b67f85be46771f5d Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 31 May 2023 18:28:35 +0300 Subject: [PATCH 6/6] Updated on 2026-08-14 --- .idea/codeStyles/Project.xml | 2 +- .../datasource/connection/RealInternetConnectionManager.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index ac3eeb6f5d..7fc608245b 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -205,4 +205,4 @@ - \ No newline at end of file + diff --git a/core/datasource/src/main/java/com/tangem/datasource/connection/RealInternetConnectionManager.kt b/core/datasource/src/main/java/com/tangem/datasource/connection/RealInternetConnectionManager.kt index 935ec93a24..2560245330 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/connection/RealInternetConnectionManager.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/connection/RealInternetConnectionManager.kt @@ -25,7 +25,7 @@ internal class RealInternetConnectionManager : NetworkConnectionManager { .observeInternetConnectivity( InternetObservingSettings.builder() .interval(PING_INTERVAL) - .build() + .build(), ) .toFlowable(BackpressureStrategy.LATEST) .asFlow()