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/common/analytics/events/Token.kt b/app/src/main/java/com/tangem/tap/common/analytics/events/Token.kt
index 46e02683ae..85dbfc7936 100644
--- a/app/src/main/java/com/tangem/tap/common/analytics/events/Token.kt
+++ b/app/src/main/java/com/tangem/tap/common/analytics/events/Token.kt
@@ -77,12 +77,6 @@ sealed class Token(
class ButtonPaste : Send("Button - Paste")
class ButtonQRCode : Send("Button - QR Code")
class ButtonSwapCurrency : Send("Button - Swap Currency")
-
- class TransactionSent(type: CurrencyType, error: Throwable? = null) : Send(
- event = "Transaction Sent",
- params = mapOf("Token" to type.value),
- error = error,
- )
}
sealed class Topup(
diff --git a/app/src/main/java/com/tangem/tap/features/disclaimer/ui/DisclaimerFragment.kt b/app/src/main/java/com/tangem/tap/features/disclaimer/ui/DisclaimerFragment.kt
index 62a0161bb8..c54f4ff005 100644
--- a/app/src/main/java/com/tangem/tap/features/disclaimer/ui/DisclaimerFragment.kt
+++ b/app/src/main/java/com/tangem/tap/features/disclaimer/ui/DisclaimerFragment.kt
@@ -3,6 +3,7 @@ package com.tangem.tap.features.disclaimer.ui
import android.os.Bundle
import android.view.View
import android.view.View.OVER_SCROLL_NEVER
+import android.webkit.WebView
import androidx.transition.TransitionInflater
import by.kirich1409.viewbindingdelegate.viewBinding
import com.tangem.core.ui.fragments.setStatusBarColor
@@ -27,21 +28,6 @@ class DisclaimerFragment : BaseFragment(R.layout.fragment_disclaimer), StoreSubs
private val binding: FragmentDisclaimerBinding by viewBinding(FragmentDisclaimerBinding::bind)
private val webViewClient = DisclaimerWebViewClient()
- override fun configureTransitions() {
- val inflater = TransitionInflater.from(requireContext())
- when (store.state.disclaimerState.showedFromScreen) {
- AppScreen.Home -> {
- enterTransition = inflater.inflateTransition(android.R.transition.slide_bottom)
- exitTransition = inflater.inflateTransition(android.R.transition.slide_top)
- }
- AppScreen.Details -> {
- enterTransition = inflater.inflateTransition(android.R.transition.fade)
- exitTransition = inflater.inflateTransition(android.R.transition.fade)
- }
- else -> {}
- }
- }
-
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
addBackPressHandler(handler = this)
@@ -86,11 +72,29 @@ class DisclaimerFragment : BaseFragment(R.layout.fragment_disclaimer), StoreSubs
super.onStop()
}
+ override fun configureTransitions() {
+ val inflater = TransitionInflater.from(requireContext())
+ when (store.state.disclaimerState.showedFromScreen) {
+ AppScreen.Home -> {
+ enterTransition = inflater.inflateTransition(android.R.transition.slide_bottom)
+ exitTransition = inflater.inflateTransition(android.R.transition.slide_top)
+ }
+ AppScreen.Details -> {
+ enterTransition = inflater.inflateTransition(android.R.transition.fade)
+ exitTransition = inflater.inflateTransition(android.R.transition.fade)
+ }
+ else -> {}
+ }
+ }
+
+ override fun handleOnBackPressed() {
+ store.dispatch(DisclaimerAction.OnBackPressed)
+ }
+
override fun newState(state: DisclaimerState) = with(binding) {
if (activity == null || view == null) return
updateUiVisibility(state.disclaimer, state.progressState)
- binding.webView.loadUrl(state.disclaimer.getUri().toString())
}
private fun updateUiVisibility(disclaimer: Disclaimer, progressState: ProgressState?) = with(binding) {
@@ -111,16 +115,19 @@ class DisclaimerFragment : BaseFragment(R.layout.fragment_disclaimer), StoreSubs
}
ProgressState.Error -> {
root.beginDelayedTransition()
- webView.hide()
- groupAccept.hide()
+ webView.show()
+ groupAccept.show()
groupLoading.hide()
- groupError.show()
+ groupError.hide()
+ webView.loadLocalTermsOfServices()
+ }
+ else -> {
+ webView.loadUrl(disclaimer.getUri().toString())
}
- else -> {}
}
}
- override fun handleOnBackPressed() {
- store.dispatch(DisclaimerAction.OnBackPressed)
+ private fun WebView.loadLocalTermsOfServices() {
+ loadData(localTermsOfServices, "text/html", "UTF-8")
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/features/disclaimer/ui/LocalTermOfServices.kt b/app/src/main/java/com/tangem/tap/features/disclaimer/ui/LocalTermOfServices.kt
new file mode 100644
index 0000000000..6651d0fa75
--- /dev/null
+++ b/app/src/main/java/com/tangem/tap/features/disclaimer/ui/LocalTermOfServices.kt
@@ -0,0 +1,66 @@
+package com.tangem.tap.features.disclaimer.ui
+
+internal val localTermsOfServices = """
+
+
+
+
+
+
+ Legal Disclaimer
+
+
+ Legal Disclaimer
+ 1. Tangem application (Software)
+ The Software is intended for usage only with Tangem hardware wallets (Cards) via NFC interface. The
+ Software DOES NOT:
+ a) Generate, store, transmit, or have access to private (secret) cryptographic keys to blockchain
+ wallets holding digital assets, including crypto-currency.
+ b) Generate, store, transmit, or have access to secret keys, passwords, passphrases, recovery phrases
+ that can be used to restore or to copy private (secret) keys to blockchain wallets holding digital assets, including
+ crypto-currency.
+ c) Provide exchange, trading, investment services on behalf of Tangem AG.
+ 2. Risks related to the use of Software
+ Tangem will not be responsible for any losses, damages or claims arising from events falling within the
+ scope of the following five categories:
+ a) Mistakes made by the user of any cryptocurrency-related software or service, e.g., forgotten
+ passwords, payments sent to wrong addresses, and accidental deletion of blockchain wallets on Cards.
+ b) Problems of Software and/or any blockchain- or cryptocurrency- related software or service, e.g.,
+ corrupted files, incorrectly constructed transactions, unsafe cryptographic libraries, malware.
+ c) Technical failures in the hardware of the user, including Cards, of any cryptocurrency-related
+ software or service, e.g., data loss due to a faulty or damaged storage device.
+ d) Security problems experienced by the user of any cryptocurrency-related software or service, e.g.,
+ unauthorized access to users' wallets and/or accounts.
+ e) Actions or inactions of third parties and/or events experienced by third parties, e.g., bankruptcy
+ of service providers, information security attacks on service providers, and fraud conducted by third parties.
+ 3. Trading and Investment risks
+ There is considerable exposure to risk in any crypto-currency or other digital asset exchange
+ transaction. Any transaction involving currencies involves risks including, but not limited to, the potential for
+ changing economic conditions that may substantially affect the price or liquidity of a currency. Investments in
+ crypto-currency exchange speculation may also be susceptible to sharp rises and falls as the relevant market values
+ fluctuate. It is for this reason that when speculating in such markets it is advisable to use only risk capital.
+ 4. Electronic Trading Risks
+ Before you engage in transactions using an electronic system, you should carefully review the rules and
+ regulations of the exchanges offering the system and/or listing the instruments you intend to trade. Online trading
+ has inherent risk due to system response and access times that may vary due to market conditions, system
+ performance, and other factors. You should understand these and additional risks before trading.
+ 5. Compliance with tax obligations
+ The users of the Software are solely responsible to determinate what, if any, taxes apply to their
+ crypto-currency transactions. The owners of, or contributors to, the Software are NOT responsible for determining
+ the taxes that apply to crypto-currency transactions.
+ 6. No warranties
+ The Software is provided on an "as is" basis without any warranties of any kind regarding the
+ Software and/or any content, data, materials and/or services provided on the Software.
+
+ 7. Limitation of liability
+ Unless otherwise required by law, in no event shall the owners of, or contributors to, the Software be
+ liable for any damages of any kind, including, but not limited to, loss of use, loss of profits, or loss of data
+ arising out of or in any way connected with the use of the Software. In no way are the owners of, or contributors
+ to, the Software responsible for the actions, decisions, or other behavior taken or not taken by you in reliance
+ upon the Software.
+ 8. Last amendment
+ This disclaimer was amended for the last time on October 1st, 2020.
+
+""".trimIndent()
\ No newline at end of file
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..c8938497e1 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,19 @@ 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 +30,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 +42,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 +111,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 +129,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 +150,7 @@ private fun sendTransaction(
walletManager: WalletManager,
amountToSend: Amount,
feeAmount: Amount,
+ feeType: FeeType,
destinationAddress: String,
transactionExtras: TransactionExtrasState,
card: CardDTO,
@@ -243,17 +236,23 @@ private fun sendTransaction(
dispatch(SendAction.ChangeSendButtonState(ButtonState.ENABLED))
tangemSdk.config.linkedTerminal = linkedTerminalState
- val currencyType = AnalyticsParam.CurrencyType.Amount(amountToSend)
when (sendResult) {
is SimpleResult.Success -> {
- Analytics.send(Token.Send.TransactionSent(currencyType))
dispatch(SendAction.SendSuccess)
if (externalTransactionData != null) {
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) {
@@ -271,8 +270,6 @@ private fun sendTransaction(
)
val error = sendResult.error as? BlockchainSdkError ?: return@withMainContext
- Analytics.send(Token.Send.TransactionSent(currencyType, error))
-
when (error) {
is BlockchainSdkError.WrappedTangemError -> {
val tangemSdkError = error.tangemError as? TangemSdkError ?: return@withMainContext
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/features/tokens/impl/presentation/ui/BriefNetworksList.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/ui/BriefNetworksList.kt
index 9ecb139cae..104ebf9d8c 100644
--- a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/ui/BriefNetworksList.kt
+++ b/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/ui/BriefNetworksList.kt
@@ -10,6 +10,7 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
+import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.key
import androidx.compose.ui.Alignment
@@ -21,6 +22,9 @@ import com.tangem.core.ui.res.TangemTheme
import com.tangem.tap.features.tokens.impl.presentation.states.NetworkItemState
import kotlinx.collections.immutable.ImmutableCollection
+/** This const configures how many items show to user and hide more than*/
+private const val MAX_VISIBLE_BRIEF_ICONS = 9
+
/**
[REDACTED_AUTHOR]
*/
@@ -37,10 +41,25 @@ internal fun BriefNetworksList(
exit = fadeOut(),
) {
Row(horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing4)) {
- networks.forEach { network ->
- key(network.name + network.protocolName) {
- BriefNetworkItem(model = network)
+ val iterator = networks.iterator()
+ var index = 0
+ while (iterator.hasNext()) {
+ val network = iterator.next()
+ if (index < MAX_VISIBLE_BRIEF_ICONS) {
+ key(network.name + network.protocolName) {
+ BriefNetworkItem(model = network)
+ }
+ } else {
+ if (networks.size < MAX_VISIBLE_BRIEF_ICONS + 1) {
+ key(network.name + network.protocolName) {
+ BriefNetworkItem(model = network)
+ }
+ } else {
+ HasMoreItem(moreCount = networks.size - index)
+ break
+ }
}
+ index++
}
}
}
@@ -50,8 +69,8 @@ internal fun BriefNetworksList(
[REDACTED_AUTHOR]
*/
@Composable
-internal fun BriefNetworkItem(model: NetworkItemState) {
- Box(modifier = Modifier.size(size = TangemTheme.dimens.size20)) {
+internal fun BriefNetworkItem(model: NetworkItemState, modifier: Modifier = Modifier) {
+ Box(modifier = modifier.size(size = TangemTheme.dimens.size20)) {
Image(
painter = painterResource(id = model.iconResId.value),
contentDescription = null,
@@ -76,4 +95,21 @@ internal fun BriefNetworkItem(model: NetworkItemState) {
}
}
}
+}
+
+@Composable
+internal fun HasMoreItem(moreCount: Int) {
+ Box(
+ modifier = Modifier
+ .size(size = TangemTheme.dimens.size20)
+ .clip(CircleShape)
+ .background(TangemTheme.colors.control.unchecked),
+ ) {
+ Text(
+ modifier = Modifier.align(Alignment.Center),
+ text = "+$moreCount",
+ style = TangemTheme.typography.overline,
+ color = TangemTheme.colors.text.tertiary,
+ )
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeMiddleware.kt b/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeMiddleware.kt
index 8cc33eca6c..9955bf6d6d 100644
--- a/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeMiddleware.kt
+++ b/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeMiddleware.kt
@@ -110,9 +110,10 @@ internal class WelcomeMiddleware {
}
private fun handleInitialIntent(intent: Intent?) {
- val isBackgroundScanWasHandled = intentHandler.handleBackgroundScan(intent, hasSavedUserWallets = true)
+ val isBackgroundScanNotHandled = !intentHandler.handleBackgroundScan(intent, hasSavedUserWallets = true)
+ val hasNotIncompletedBackup = !backupService.hasIncompletedBackup
- if (!isBackgroundScanWasHandled) {
+ if (isBackgroundScanNotHandled && hasNotIncompletedBackup) {
store.dispatchOnMain(WelcomeAction.ProceedWithBiometrics)
}
}
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/app/src/main/res/layout/fragment_shop.xml b/app/src/main/res/layout/fragment_shop.xml
index c3dadcdb4b..523b68c535 100644
--- a/app/src/main/res/layout/fragment_shop.xml
+++ b/app/src/main/res/layout/fragment_shop.xml
@@ -132,7 +132,7 @@
android:paddingStart="3dp"
android:paddingTop="3dp"
android:paddingEnd="3dp"
- app:layout_constraintBottom_toTopOf="@id/v_shipping_discount_background"
+ app:layout_constraintBottom_toTopOf="@id/ll_total"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:selectionRequired="true"
@@ -156,162 +156,125 @@
app:chipMinTouchTargetSize="0dp" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ android:orientation="vertical"
+ app:layout_constraintBottom_toTopOf="@id/ll_buttons">
-
+
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
= ReactiveNetwork
- .observeInternetConnectivity()
+ .observeInternetConnectivity(
+ InternetObservingSettings.builder()
+ .interval(PING_INTERVAL)
+ .build(),
+ )
.toFlowable(BackpressureStrategy.LATEST)
.asFlow()
- .stateIn(scope, SharingStarted.Eagerly, initialValue = false)
+ .stateIn(scope, SharingStarted.Lazily, initialValue = initialNetworkResult)
override val isOnline: Boolean
get() = isOnlineFlow.value
diff --git a/core/res/src/main/res/values-ru/strings.xml b/core/res/src/main/res/values-ru/strings.xml
index 0fe972b284..2baace2c4d 100644
--- a/core/res/src/main/res/values-ru/strings.xml
+++ b/core/res/src/main/res/values-ru/strings.xml
@@ -333,11 +333,10 @@
Транзакция успешно подписана и отправлена в блокчейн. Баланс будет обновлен через некоторое время
Неверный адрес
Купить сейчас
- Бесплатно
У меня есть промо-код…
Tangem Wallet
Другие способы оплаты
- Доставка
+ Из-за большого количества заказов, которые мы получаем, cроки доставки могут быть увеличены.
Итого
Сеть Solana взимает арендную плату в размере %1$s каждые 2 дня. Аккаунты, которые не могут позволить себе арендную плату, удаляются из сети. Пополните свой счет более чем на %2$s, чтобы не платить арендную плату.
Держите свои криптосбережения в безопасности. Приватные ключи надежно хранятся на карте.
diff --git a/core/res/src/main/res/values-zh-rTW/strings.xml b/core/res/src/main/res/values-zh-rTW/strings.xml
index d53dd02d89..08f4e9e68b 100644
--- a/core/res/src/main/res/values-zh-rTW/strings.xml
+++ b/core/res/src/main/res/values-zh-rTW/strings.xml
@@ -323,11 +323,9 @@
交易已成功簽署並發送至區塊鏈節點。錢包餘額稍後更新
無效地址
現在購買
- 免費
輸入折扣碼
Tangem Wallet
其他付款方式
- 運送
總計
Solana 網絡每 2 天收取 %1$s 的費用。無法付此費用的帳戶將從網絡中清除。向您的帳戶存入超過 %2$s 即可免費使用
安全地存儲您的加密貨幣,同時將私鑰保存在您的卡中
diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml
index 3ce5104d33..ea3c2c3c93 100644
--- a/core/res/src/main/res/values/strings.xml
+++ b/core/res/src/main/res/values/strings.xml
@@ -329,11 +329,10 @@
Transaction has been successfully signed and sent to the blockchain node. Wallet balance will be updated in a while
Invalid address
Buy now
- Free
I have a promo code…
Tangem Wallet
Other payment methods
- Shipping
+ Due to the high volume of orders we are receiving, Shipping and Local Delivery orders may be delayed.
Total
Solana network charges a rent of %1$s every 2 days. Accounts that can\'t afford the rent are purged from the network. Deposit your account with more than %2$s to use it for free.
Store your crypto assets secure while keeping private keys contained in your card
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..f3f193b180 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,
),
)
}
@@ -670,8 +682,8 @@ 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_GAS_LIMIT_BY = 125 // 25%
+ 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 = 112 // 12%
private const val USDT_SYMBOL = "USDT"
private const val USDC_SYMBOL = "USDC"
private const val INFINITY_SYMBOL = "∞"
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 27e4b3c750..f5a39df29e 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/gradle/dependencies.toml b/gradle/dependencies.toml
index d92341d185..06b3dd6a6b 100644
--- a/gradle/dependencies.toml
+++ b/gradle/dependencies.toml
@@ -75,9 +75,9 @@ reactiveNetwork = "3.0.8"
# endregion Other libraries
# region Tangem
-tangemBlockchainSdk = "develop-237"
+tangemBlockchainSdk = "develop-240"
#tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds
-tangemCardSdk = "develop-249"
+tangemCardSdk = "develop-266"
#tangemCardSdk = "0.0.1" # Keep it! - used for local builds
# endregion Tangem
@@ -179,7 +179,7 @@ appsflyer = { module = "com.appsflyer:af-android-sdk", version.ref = "appsflyer"
armadillo = { module = "at.favre.lib:armadillo", version.ref = "armadillo" }
coil = { module = "io.coil-kt:coil", version.ref = "coil" }
kotlin-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutine" }
-kotlin-coroutines-reactive = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-reactive", version.ref = "coroutine" }
+kotlin-coroutines-rx2 = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-rx2", version.ref = "coroutine" }
kotlin-immutable-collections = { module = "org.jetbrains.kotlinx:kotlinx-collections-immutable", version.ref = "kotlin-immutable-collections" }
desugar = { module = "com.android.tools:desugar_jdk_libs", version.ref = "desugarJdkLibs" }
googlePlay-core = { module = "com.google.android.play:core", version.ref = "googlePlayCore" }
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