Updated on 2026-08-14

This commit is contained in:
Tangem 2021-04-07 19:30:14 +03:00
parent 40ed67b0c2
commit a6618b4d35
5 changed files with 102 additions and 67 deletions

View file

@ -69,7 +69,7 @@ class TapApplication : Application() {
private fun initFeedbackManager() {
val infoHolder = AdditionalEmailInfo()
infoHolder.updateAppVersion(this)
infoHolder.setAppVersion(this)
val logWriter = TangemLogCollector()
Log.addLogger(logWriter)

View file

@ -85,9 +85,9 @@ class TapWalletManager {
FirebaseAnalyticsHandler.triggerEvent(AnalyticsEvent.CARD_IS_SCANNED, data.card)
}
TapWorkarounds.updateCard(data.card)
store.state.globalState.feedbackManager?.infoHolder?.setCardInfo(data.card)
store.state.globalState.warningManager?.setBlockchain(data.walletManager?.wallet?.blockchain)
updateConfigManager(data)
updateFeedbackManager(data)
withContext(Dispatchers.Main) {
store.dispatch(WalletAction.ResetState)
@ -125,19 +125,6 @@ class TapWalletManager {
}
}
private fun updateFeedbackManager(data: ScanNoteResponse) {
val card = data.card
val wallet = data.walletManager?.wallet ?: return
val infoHolder = store.state.globalState.feedbackManager?.infoHolder ?: return
infoHolder.cardId = card.cardId
infoHolder.cardFirmwareVersion = card.firmwareVersion.version
infoHolder.signedHashesCount = card.walletSignedHashes?.toString() ?: "0"
infoHolder.sourceAddress = wallet.address
infoHolder.explorerLink = wallet.getExploreUrl(wallet.address)
infoHolder.blockchain = wallet.blockchain
}
suspend fun loadData(data: ScanNoteResponse) {
withContext(Dispatchers.Main) {
store.dispatch(WalletAction.Warnings.CheckIfNeeded)

View file

@ -12,7 +12,13 @@ import androidx.core.content.ContextCompat
import androidx.core.content.FileProvider
import com.tangem.Log
import com.tangem.TangemSdkLogger
import com.tangem.blockchain.common.Amount
import com.tangem.blockchain.common.AmountType
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.Wallet
import com.tangem.commands.common.card.Card
import com.tangem.tap.common.extensions.stripZeroPlainString
import com.tangem.tap.store
import timber.log.Timber
import java.io.File
import java.io.FileWriter
@ -114,26 +120,36 @@ class TangemLogCollector : TangemSdkLogger {
}
class AdditionalEmailInfo {
var cardId: String = ""
var cardFirmwareVersion: String = ""
var blockchain: Blockchain = Blockchain.Unknown
class EmailWalletInfo(
var blockchain: Blockchain = Blockchain.Unknown,
var address: String = "",
var explorerLink: String = "",
// var outputsCount: String = ""
// var transactionHex: String = ""
)
var phoneModel: String = Build.MODEL
var osVersion: String = Build.VERSION.SDK_INT.toString()
var appVersion: String = ""
var token: String = ""
var sourceAddress: String = ""
// card
var cardId: String = ""
var cardFirmwareVersion: String = ""
// wallets
internal val walletsInfo = mutableListOf<EmailWalletInfo>()
internal var onSendErrorWalletInfo: EmailWalletInfo? = null
var signedHashesCount: String = ""
// device
var phoneModel: String = Build.MODEL
var osVersion: String = Build.VERSION.SDK_INT.toString()
// send error
var destinationAddress: String = ""
var amount: String = ""
var fee: String = ""
var token: String = ""
// var transactionHex: String = ""
var signedHashesCount: String = ""
var explorerLink: String = ""
// var outputsCount: String = ""
fun updateAppVersion(context: Context) {
fun setAppVersion(context: Context) {
try {
val pInfo = context.packageManager.getPackageInfo(context.packageName, 0)
appVersion = pInfo.versionName
@ -141,6 +157,51 @@ class AdditionalEmailInfo {
e.printStackTrace()
}
}
fun setCardInfo(card: Card) {
cardId = card.cardId
cardFirmwareVersion = card.firmwareVersion.version
signedHashesCount = card.walletSignedHashes?.toString() ?: "0"
}
fun setWalletsInfo(wallets: List<Wallet>) {
walletsInfo.clear()
wallets.forEach { walletsInfo.add(EmailWalletInfo(it.blockchain, getAddress(it), getExploreUri(it))) }
}
fun updateOnSendError(wallet: Wallet, amountToSend: Amount, feeAmount: Amount, destinationAddress: String) {
val amountState = store.state.sendState.amountState
onSendErrorWalletInfo = EmailWalletInfo(wallet.blockchain, getAddress(wallet), getExploreUri(wallet))
this.destinationAddress = destinationAddress
amount = amountToSend.value?.stripZeroPlainString() ?: "0"
fee = feeAmount.value?.stripZeroPlainString() ?: "0"
if (amountState.typeOfAmount is AmountType.Token) {
token = amountState.amountToExtract?.currencySymbol ?: ""
}
}
private fun getAddress(wallet: Wallet): String {
return if (wallet.addresses.size == 1) {
wallet.address
} else {
val addresses = wallet.addresses.joinToString(", ") {
"${it.type.javaClass.simpleName} - ${it.value}"
}
"Multiple address: $addresses"
}
}
private fun getExploreUri(wallet: Wallet): String {
return if (wallet.addresses.size == 1) {
wallet.getExploreUrl(wallet.address)
} else {
val links = wallet.addresses.joinToString(", ") {
"${it.type.javaClass.simpleName} - ${wallet.getExploreUrl(it.value)}"
}
"Multiple explorers links: $links"
}
}
}
interface EmailData {
@ -160,9 +221,10 @@ class RateCanBeBetterEmail : EmailData {
override val mainMessage: String = "Tell us what functions you are missing, and we will try to help you."
override fun createOptionalMessage(infoHolder: AdditionalEmailInfo): String {
val walletInfo = infoHolder.walletsInfo[0]
return StringBuilder().apply {
appendKeyValue("Card ID", infoHolder.cardId)
appendKeyValue("Blockchain", infoHolder.blockchain.fullName)
appendKeyValue("Blockchain", walletInfo.blockchain.fullName)
appendKeyValue("Phone model", infoHolder.phoneModel)
appendKeyValue("OS version", infoHolder.osVersion)
appendKeyValue("App version", infoHolder.appVersion)
@ -186,12 +248,13 @@ class SendTransactionFailedEmail(private val error: String) : EmailData {
override val subject: String = "Cant send a transaction"
override val mainMessage: String = "Please tell us more about your issue. Every small detail can help."
override fun createOptionalMessage(infoHolder: AdditionalEmailInfo): String {
val walletInfo = infoHolder.onSendErrorWalletInfo ?: AdditionalEmailInfo.EmailWalletInfo()
return StringBuilder().apply {
appendKeyValue("Error", error)
appendKeyValue("Card ID", infoHolder.cardId)
appendKeyValue("Blockchain", infoHolder.blockchain.fullName)
appendKeyValue("Blockchain", walletInfo.blockchain.fullName)
appendKeyValue("Token", infoHolder.token)
appendKeyValue("Source address", infoHolder.sourceAddress)
appendKeyValue("Source address", walletInfo.address)
appendKeyValue("Destination address", infoHolder.destinationAddress)
appendKeyValue("Amount", infoHolder.amount)
appendKeyValue("Fee", infoHolder.fee)
@ -208,17 +271,20 @@ class FeedbackEmail : EmailData {
override val subject: String = "Tangem Tap feedback"
override val mainMessage: String = "Hi Tangem,"
override fun createOptionalMessage(infoHolder: AdditionalEmailInfo): String {
return StringBuilder().apply {
appendKeyValue("Card ID", infoHolder.cardId)
appendKeyValue("Firmware version", infoHolder.cardFirmwareVersion)
appendKeyValue("Signed hashes", infoHolder.signedHashesCount)
appendKeyValue("Blockchain", infoHolder.blockchain.fullName)
appendKeyValue("Wallet address", infoHolder.sourceAddress)
appendKeyValue("Explorer link", infoHolder.explorerLink)
val builder = StringBuilder()
builder.appendKeyValue("Card ID", infoHolder.cardId)
builder.appendKeyValue("Firmware version", infoHolder.cardFirmwareVersion)
builder.appendKeyValue("Signed hashes", infoHolder.signedHashesCount)
infoHolder.walletsInfo.forEach {
builder.appendKeyValue("Blockchain", it.blockchain.fullName)
builder.appendKeyValue("Wallet address", it.address)
builder.appendKeyValue("Explorer link", it.explorerLink)
}
// appendKeyValue("Outputs count", infoHolder.outputsCount)
appendKeyValue("Phone model", infoHolder.phoneModel)
appendKeyValue("OS version", infoHolder.osVersion)
}.toString()
builder.appendKeyValue("Phone model", infoHolder.phoneModel)
builder.appendKeyValue("OS version", infoHolder.osVersion)
return builder.toString()
}
}

View file

@ -145,10 +145,11 @@ private fun sendTransaction(
is Throwable -> {
val throwable = result.error as Throwable
val message = throwable.message
val infoHolder = store.state.globalState.feedbackManager?.infoHolder
when {
message == null -> {
dispatch(SendAction.SendError(TapError.UnknownError))
updateFeedbackManager(walletManager, amountToSend, feeAmount, destinationAddress, card)
infoHolder?.updateOnSendError(walletManager.wallet, amountToSend, feeAmount, destinationAddress)
dispatch(SendAction.Dialog.SendTransactionFails("unknown error"))
}
message.contains("50002") -> {
@ -163,7 +164,7 @@ private fun sendTransaction(
Timber.e(throwable)
FirebaseCrashlytics.getInstance().recordException(throwable)
dispatch(SendAction.SendError(TapError.CustomError(message)))
updateFeedbackManager(walletManager, amountToSend, feeAmount, destinationAddress, card)
infoHolder?.updateOnSendError(walletManager.wallet, amountToSend, feeAmount, destinationAddress)
dispatch(SendAction.Dialog.SendTransactionFails(message))
}
}
@ -176,29 +177,6 @@ private fun sendTransaction(
}
}
private fun updateFeedbackManager(
walletManager: WalletManager,
amountToSend: Amount,
feeAmount: Amount,
destinationAddress: String,
card: Card,
) {
val infoHolder = store.state.globalState.feedbackManager?.infoHolder ?: return
val amountState = store.state.sendState.amountState
infoHolder.cardId = card.cardId
infoHolder.blockchain = walletManager.wallet.blockchain
infoHolder.sourceAddress = walletManager.wallet.address
infoHolder.destinationAddress = destinationAddress
infoHolder.amount = amountToSend.value?.stripZeroPlainString() ?: "0"
infoHolder.fee = feeAmount.value?.stripZeroPlainString() ?: "0"
infoHolder.cardFirmwareVersion = card.firmwareVersion.version
if (amountState.typeOfAmount is AmountType.Token) {
infoHolder.token = amountState.amountToExtract?.currencySymbol ?: ""
}
// infoHolder.transactionHex = ""
}
fun extractErrorsForAmountField(errors: EnumSet<TransactionError>): EnumSet<TransactionError> {
val showIntoAmountField = EnumSet.noneOf(TransactionError::class.java)
errors.forEach {

View file

@ -19,9 +19,13 @@ import kotlinx.coroutines.withContext
class MultiWalletMiddleware {
fun handle(
action: WalletAction.MultiWallet, walletState: WalletState?, globalState: GlobalState?
action: WalletAction.MultiWallet, walletState: WalletState?, globalState: GlobalState?,
) {
when (action) {
is WalletAction.MultiWallet.AddWalletManagers -> {
val wallets = action.walletManagers.map { it.wallet }
store.state.globalState.feedbackManager?.infoHolder?.setWalletsInfo(wallets)
}
is WalletAction.MultiWallet.SelectWallet -> {
if (action.walletData != null) {
store.dispatch(NavigationAction.NavigateTo(AppScreen.WalletDetails))