Updated on 2026-08-14
This commit is contained in:
parent
5f1f826412
commit
7a177e3467
13 changed files with 274 additions and 100 deletions
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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 -> {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue