Updated on 2026-08-14
This commit is contained in:
commit
72a99c59e6
11 changed files with 70 additions and 52 deletions
|
|
@ -153,7 +153,7 @@ class DialogManager : StoreSubscriber<GlobalState> {
|
|||
primaryButtonAction = state.dialog.onOk,
|
||||
)
|
||||
is WalletDialog.RussianCardholdersWarningDialog ->
|
||||
RussianCardholdersWarningBottomSheetDialog(context)
|
||||
RussianCardholdersWarningBottomSheetDialog(context, state.dialog.topUpUrl)
|
||||
else -> null
|
||||
}
|
||||
dialog?.show()
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@ import kotlin.collections.set
|
|||
|
||||
class WalletConnectManager {
|
||||
|
||||
private var cardId: String? = null
|
||||
|
||||
private val okHttpClient: OkHttpClient by lazy {
|
||||
OkHttpClient.Builder()
|
||||
.connectTimeout(20, TimeUnit.SECONDS)
|
||||
|
|
@ -138,6 +140,7 @@ class WalletConnectManager {
|
|||
fun restoreSessions(scanResponse: ScanResponse) {
|
||||
val walletPublicKey = scanResponse.card.wallets.firstOrNull { it.curve == EllipticCurve.Secp256k1 }?.publicKey
|
||||
?: return
|
||||
if (scanResponse.card.backupStatus?.isActive != true) cardId = scanResponse.card.cardId
|
||||
val sessions = walletConnectRepository.loadSavedSessions()
|
||||
// filter sessions for this particular card
|
||||
.filter { it.wallet.walletPublicKey.contentEquals(walletPublicKey) }
|
||||
|
|
@ -223,10 +226,10 @@ class WalletConnectManager {
|
|||
}
|
||||
|
||||
private fun onSessionClosed(session: WCSession) {
|
||||
store.state.globalState.analyticsHandler?.logWcEvent(
|
||||
store.state.globalState.analyticsHandler.logWcEvent(
|
||||
AnalyticsAnOld.WcAnalyticsEvent.Session(
|
||||
AnalyticsAnOld.WcSessionEvent.Disconnect, sessions[session]?.peerMeta?.url
|
||||
)
|
||||
AnalyticsAnOld.WcSessionEvent.Disconnect, sessions[session]?.peerMeta?.url,
|
||||
),
|
||||
)
|
||||
sessions.remove(session)
|
||||
walletConnectRepository.removeSession(session)
|
||||
|
|
@ -272,13 +275,13 @@ class WalletConnectManager {
|
|||
val activeData = sessions[session]
|
||||
val data = activeData?.transactionData ?: return
|
||||
scope.launch {
|
||||
val hash = WalletConnectSdkHelper().completeTransaction(data).guard {
|
||||
val hash = WalletConnectSdkHelper().completeTransaction(data, cardId).guard {
|
||||
sessions[data.session.session] = activeData.copy(transactionData = null)
|
||||
store.dispatchOnMain(
|
||||
WalletConnectAction.RejectRequest(
|
||||
data.session.session,
|
||||
data.id
|
||||
)
|
||||
data.id,
|
||||
),
|
||||
)
|
||||
return@launch
|
||||
}
|
||||
|
|
@ -292,12 +295,12 @@ class WalletConnectManager {
|
|||
) {
|
||||
val activeData = sessions[sessionData] ?: return
|
||||
scope.launch {
|
||||
val hash = WalletConnectSdkHelper().signBnbTransaction(data, activeData).guard {
|
||||
val hash = WalletConnectSdkHelper().signBnbTransaction(data, activeData, cardId).guard {
|
||||
store.dispatchOnMain(
|
||||
WalletConnectAction.RejectRequest(
|
||||
sessionData,
|
||||
id
|
||||
)
|
||||
id,
|
||||
),
|
||||
)
|
||||
return@launch
|
||||
}
|
||||
|
|
@ -330,14 +333,14 @@ class WalletConnectManager {
|
|||
val activeData = sessions[session]
|
||||
val data = activeData?.personalSignData ?: return
|
||||
scope.launch {
|
||||
val hash = WalletConnectSdkHelper().signPersonalMessage(data.hash, activeData.wallet)
|
||||
val hash = WalletConnectSdkHelper().signPersonalMessage(data.hash, activeData.wallet, cardId)
|
||||
.guard {
|
||||
sessions[data.session.session] = activeData.copy(transactionData = null)
|
||||
store.dispatchOnMain(
|
||||
WalletConnectAction.RejectRequest(
|
||||
data.session.session,
|
||||
data.id
|
||||
)
|
||||
data.id,
|
||||
),
|
||||
)
|
||||
return@launch
|
||||
}
|
||||
|
|
@ -372,7 +375,7 @@ class WalletConnectManager {
|
|||
),
|
||||
)
|
||||
}
|
||||
store.state.globalState.analyticsHandler?.logWcEvent(
|
||||
store.state.globalState.analyticsHandler.logWcEvent(
|
||||
AnalyticsAnOld.WcAnalyticsEvent.Session(
|
||||
AnalyticsAnOld.WcSessionEvent.Connect, peer.url,
|
||||
),
|
||||
|
|
@ -387,10 +390,10 @@ class WalletConnectManager {
|
|||
}
|
||||
client.onEthSendTransaction = { id: Long, transaction: WCEthereumTransaction ->
|
||||
Timber.d("onEthSendTransaction: $transaction")
|
||||
store.state.globalState.analyticsHandler?.logWcEvent(
|
||||
store.state.globalState.analyticsHandler.logWcEvent(
|
||||
AnalyticsAnOld.WcAnalyticsEvent.Action(
|
||||
AnalyticsAnOld.WcAction.SendTransaction
|
||||
)
|
||||
AnalyticsAnOld.WcAction.SendTransaction,
|
||||
),
|
||||
)
|
||||
sessions[client.session]?.toWalletConnectSession()?.let { sessionData ->
|
||||
store.dispatchOnMain(
|
||||
|
|
@ -405,10 +408,10 @@ class WalletConnectManager {
|
|||
}
|
||||
client.onEthSignTransaction = { id: Long, transaction: WCEthereumTransaction ->
|
||||
Timber.d("onEthSignTransaction: $transaction")
|
||||
store.state.globalState.analyticsHandler?.logWcEvent(
|
||||
store.state.globalState.analyticsHandler.logWcEvent(
|
||||
AnalyticsAnOld.WcAnalyticsEvent.Action(
|
||||
AnalyticsAnOld.WcAction.SignTransaction
|
||||
)
|
||||
AnalyticsAnOld.WcAction.SignTransaction,
|
||||
),
|
||||
)
|
||||
sessions[client.session]?.toWalletConnectSession()?.let { sessionData ->
|
||||
store.dispatchOnMain(
|
||||
|
|
@ -423,10 +426,10 @@ class WalletConnectManager {
|
|||
}
|
||||
client.onEthSign = { id: Long, message: WCEthereumSignMessage ->
|
||||
Timber.d("onEthSign: $message")
|
||||
store.state.globalState.analyticsHandler?.logWcEvent(
|
||||
store.state.globalState.analyticsHandler.logWcEvent(
|
||||
AnalyticsAnOld.WcAnalyticsEvent.Action(
|
||||
AnalyticsAnOld.WcAction.PersonalSign
|
||||
)
|
||||
AnalyticsAnOld.WcAction.PersonalSign,
|
||||
),
|
||||
)
|
||||
sessions[client.session]?.toWalletConnectSession()?.let { sessionData ->
|
||||
store.dispatchOnMain(
|
||||
|
|
@ -499,10 +502,10 @@ class WalletConnectManager {
|
|||
val message = EthSignHelper.tryToParseEthTypedMessage(request)
|
||||
if (message != null) {
|
||||
Timber.d("onEthSign_v4: $message")
|
||||
store.state.globalState.analyticsHandler?.logWcEvent(
|
||||
store.state.globalState.analyticsHandler.logWcEvent(
|
||||
AnalyticsAnOld.WcAnalyticsEvent.Action(
|
||||
AnalyticsAnOld.WcAction.PersonalSign
|
||||
)
|
||||
AnalyticsAnOld.WcAction.PersonalSign,
|
||||
),
|
||||
)
|
||||
sessions[client.session]?.toWalletConnectSession()?.let { sessionData ->
|
||||
store.dispatchOnMain(
|
||||
|
|
|
|||
|
|
@ -126,24 +126,24 @@ class WalletConnectSdkHelper {
|
|||
)
|
||||
}
|
||||
|
||||
suspend fun completeTransaction(data: WcTransactionData): String? {
|
||||
suspend fun completeTransaction(data: WcTransactionData, cardId: String?): String? {
|
||||
return when (data.type) {
|
||||
WcTransactionType.EthSendTransaction -> sendTransaction(data)
|
||||
WcTransactionType.EthSignTransaction -> signTransaction(data)
|
||||
WcTransactionType.EthSendTransaction -> sendTransaction(data, cardId)
|
||||
WcTransactionType.EthSignTransaction -> signTransaction(data, cardId)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun sendTransaction(data: WcTransactionData): String? {
|
||||
private suspend fun sendTransaction(data: WcTransactionData, cardId: String?): String? {
|
||||
val result = (data.walletManager as TransactionSender).send(
|
||||
transactionData = data.transaction,
|
||||
signer = CommonSigner(tangemSdk)
|
||||
signer = CommonSigner(tangemSdk, cardId),
|
||||
)
|
||||
return when (result) {
|
||||
SimpleResult.Success -> {
|
||||
HEX_PREFIX + data.walletManager.wallet.recentTransactions.last().hash
|
||||
}
|
||||
is SimpleResult.Failure -> {
|
||||
store.state.globalState.analyticsHandler?.handleBlockchainSdkErrorEvent(
|
||||
store.state.globalState.analyticsHandler.handleBlockchainSdkErrorEvent(
|
||||
result.error,
|
||||
AnalyticsAnOld.ActionToLog.WalletConnectTransaction,
|
||||
)
|
||||
|
|
@ -153,27 +153,27 @@ class WalletConnectSdkHelper {
|
|||
}
|
||||
}
|
||||
|
||||
private suspend fun signTransaction(data: WcTransactionData): String? {
|
||||
private suspend fun signTransaction(data: WcTransactionData, cardId: String?): String? {
|
||||
val dataToSign = EthereumUtils.buildTransactionToSign(
|
||||
transactionData = data.transaction,
|
||||
nonce = null,
|
||||
blockchain = data.walletManager.wallet.blockchain,
|
||||
gasLimit = null
|
||||
gasLimit = null,
|
||||
) ?: return null
|
||||
|
||||
val command = SignHashCommand(
|
||||
hash = dataToSign.hash,
|
||||
walletPublicKey = data.walletManager.wallet.publicKey.seedKey,
|
||||
derivationPath = data.walletManager.wallet.publicKey.derivationPath
|
||||
derivationPath = data.walletManager.wallet.publicKey.derivationPath,
|
||||
)
|
||||
val result = tangemSdkManager.runTaskAsync(command, initialMessage = Message())
|
||||
val result = tangemSdkManager.runTaskAsync(command, initialMessage = Message(), cardId = cardId)
|
||||
return when (result) {
|
||||
is CompletionResult.Success -> {
|
||||
HEX_PREFIX + result.data
|
||||
}
|
||||
is CompletionResult.Failure -> {
|
||||
(result.error as? TangemSdkError)?.let { error ->
|
||||
store.state.globalState.analyticsHandler?.handleCardSdkErrorEvent(
|
||||
store.state.globalState.analyticsHandler.handleCardSdkErrorEvent(
|
||||
error,
|
||||
AnalyticsAnOld.ActionToLog.WalletConnectSign,
|
||||
)
|
||||
|
|
@ -184,13 +184,13 @@ class WalletConnectSdkHelper {
|
|||
}
|
||||
}
|
||||
|
||||
suspend fun signBnbTransaction(data: ByteArray, session: WalletConnectActiveData): String? {
|
||||
suspend fun signBnbTransaction(data: ByteArray, session: WalletConnectActiveData, cardId: String?): String? {
|
||||
val command = SignHashCommand(
|
||||
hash = data,
|
||||
walletPublicKey = session.wallet.walletPublicKey ?: return null,
|
||||
derivationPath = session.wallet.derivationPath
|
||||
derivationPath = session.wallet.derivationPath,
|
||||
)
|
||||
val result = tangemSdkManager.runTaskAsync(command, initialMessage = Message())
|
||||
val result = tangemSdkManager.runTaskAsync(command, initialMessage = Message(), cardId = cardId)
|
||||
return when (result) {
|
||||
is CompletionResult.Success -> {
|
||||
val key = session.wallet.derivedPublicKey?.toDecompressedPublicKey()
|
||||
|
|
@ -202,7 +202,7 @@ class WalletConnectSdkHelper {
|
|||
}
|
||||
is CompletionResult.Failure -> {
|
||||
(result.error as? TangemSdkError)?.let { error ->
|
||||
store.state.globalState.analyticsHandler?.handleCardSdkErrorEvent(
|
||||
store.state.globalState.analyticsHandler.handleCardSdkErrorEvent(
|
||||
error,
|
||||
AnalyticsAnOld.ActionToLog.WalletConnectTransaction,
|
||||
)
|
||||
|
|
@ -266,10 +266,10 @@ class WalletConnectSdkHelper {
|
|||
}.joinToString("")
|
||||
}
|
||||
|
||||
suspend fun signPersonalMessage(hashToSign: ByteArray, wallet: WalletForSession): String? {
|
||||
suspend fun signPersonalMessage(hashToSign: ByteArray, wallet: WalletForSession, cardId: String?): String? {
|
||||
val key = wallet.derivedPublicKey ?: wallet.walletPublicKey
|
||||
val command = SignHashCommand(hashToSign, wallet.walletPublicKey!!, wallet.derivationPath)
|
||||
return when (val result = tangemSdkManager.runTaskAsync(command)) {
|
||||
return when (val result = tangemSdkManager.runTaskAsync(command, cardId)) {
|
||||
is CompletionResult.Success -> {
|
||||
val hash = result.data.signature
|
||||
return EthereumUtils.prepareSignedMessageData(
|
||||
|
|
@ -278,7 +278,7 @@ class WalletConnectSdkHelper {
|
|||
}
|
||||
is CompletionResult.Failure -> {
|
||||
(result.error as? TangemSdkError)?.let { error ->
|
||||
store.state.globalState.analyticsHandler?.handleCardSdkErrorEvent(
|
||||
store.state.globalState.analyticsHandler.handleCardSdkErrorEvent(
|
||||
error,
|
||||
AnalyticsAnOld.ActionToLog.WalletConnectSign,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import com.tangem.domain.common.extensions.withMainContext
|
|||
import com.tangem.tap.DELAY_SDK_DIALOG_CLOSE
|
||||
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.dispatchOpenUrl
|
||||
import com.tangem.tap.common.extensions.getAddressData
|
||||
import com.tangem.tap.common.extensions.getToUpUrl
|
||||
|
|
@ -20,8 +21,10 @@ import com.tangem.tap.domain.TapError
|
|||
import com.tangem.tap.domain.extensions.hasWallets
|
||||
import com.tangem.tap.domain.extensions.makePrimaryWalletManager
|
||||
import com.tangem.tap.features.demo.DemoHelper
|
||||
import com.tangem.tap.features.home.RUSSIA_COUNTRY_CODE
|
||||
import com.tangem.tap.features.wallet.models.Currency
|
||||
import com.tangem.tap.features.wallet.redux.ProgressState
|
||||
import com.tangem.tap.features.wallet.redux.WalletAction
|
||||
import com.tangem.tap.scope
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.tap.tangemSdkManager
|
||||
|
|
@ -152,6 +155,10 @@ private fun handleNoteAction(appState: () -> AppState?, action: Action, dispatch
|
|||
}
|
||||
is OnboardingNoteAction.TopUp -> {
|
||||
val topUpUrl = noteState.walletManager?.getToUpUrl() ?: return
|
||||
if (globalState.userCountryCode == RUSSIA_COUNTRY_CODE) {
|
||||
store.dispatchOnMain(WalletAction.DialogAction.RussianCardholdersWarningDialog(topUpUrl))
|
||||
return
|
||||
}
|
||||
store.dispatchOpenUrl(topUpUrl)
|
||||
}
|
||||
OnboardingNoteAction.Done -> {
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ sealed class WalletAction : Action {
|
|||
object SignedHashesMultiWalletDialog : DialogAction()
|
||||
object ChooseTradeActionDialog : DialogAction()
|
||||
data class ChooseCurrency(val amounts: List<Amount>?) : DialogAction()
|
||||
object RussianCardholdersWarningDialog : DialogAction()
|
||||
data class RussianCardholdersWarningDialog(val topUpUrl: String? = null) : DialogAction()
|
||||
|
||||
object Hide : DialogAction()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ class TradeCryptoMiddleware {
|
|||
action: WalletAction.TradeCryptoAction.Buy,
|
||||
) {
|
||||
if (action.checkUserLocation && state()?.globalState?.userCountryCode == RUSSIA_COUNTRY_CODE) {
|
||||
store.dispatchOnMain(WalletAction.DialogAction.RussianCardholdersWarningDialog)
|
||||
store.dispatchOnMain(WalletAction.DialogAction.RussianCardholdersWarningDialog())
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ class WalletDialogsMiddleware {
|
|||
)
|
||||
}
|
||||
is WalletAction.DialogAction.RussianCardholdersWarningDialog -> {
|
||||
store.dispatchDialogShow(WalletDialog.RussianCardholdersWarningDialog)
|
||||
store.dispatchDialogShow(WalletDialog.RussianCardholdersWarningDialog(action.topUpUrl))
|
||||
}
|
||||
is WalletAction.DialogAction.Hide -> {
|
||||
store.dispatchDialogHide()
|
||||
|
|
|
|||
|
|
@ -31,5 +31,5 @@ sealed interface WalletDialog : StateDialog {
|
|||
val titleRes: Int = R.string.token_details_unable_hide_alert_title
|
||||
}
|
||||
|
||||
object RussianCardholdersWarningDialog : WalletDialog
|
||||
data class RussianCardholdersWarningDialog(val topUpUrl: String?) : WalletDialog
|
||||
}
|
||||
|
|
@ -88,7 +88,7 @@ class OnWalletLoadedReducer {
|
|||
val tokenFiatAmountFormatted = tokenFiatAmount?.toFormattedFiatValue(fiatCurrency.symbol)
|
||||
?: UNKNOWN_AMOUNT_SIGN
|
||||
|
||||
val isTokenSendButtonEnabled = newWalletData.shouldEnableTokenSendButton()
|
||||
val isTokenSendButtonEnabled = tokenWalletData?.shouldEnableTokenSendButton() == true
|
||||
&& pendingTransactions.isEmpty()
|
||||
tokenWalletData?.copy(
|
||||
currencyData = tokenWalletData.currencyData.copy(
|
||||
|
|
|
|||
|
|
@ -5,12 +5,16 @@ import android.os.Bundle
|
|||
import android.view.LayoutInflater
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import com.tangem.tap.common.extensions.dispatchDialogHide
|
||||
import com.tangem.tap.common.extensions.dispatchOpenUrl
|
||||
import com.tangem.tap.common.redux.navigation.NavigationAction
|
||||
import com.tangem.tap.features.wallet.redux.WalletAction
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.wallet.databinding.DialogRussiansCardholdersWarningBinding
|
||||
|
||||
class RussianCardholdersWarningBottomSheetDialog(context: Context) : BottomSheetDialog(context) {
|
||||
class RussianCardholdersWarningBottomSheetDialog(
|
||||
context: Context, private val topUpUrl: String?,
|
||||
) : BottomSheetDialog
|
||||
(context) {
|
||||
|
||||
private var binding: DialogRussiansCardholdersWarningBinding? = null
|
||||
|
||||
|
|
@ -29,7 +33,11 @@ class RussianCardholdersWarningBottomSheetDialog(context: Context) : BottomSheet
|
|||
}
|
||||
|
||||
binding?.btnYes?.setOnClickListener {
|
||||
store.dispatch(WalletAction.TradeCryptoAction.Buy(checkUserLocation = false))
|
||||
if (topUpUrl != null) {
|
||||
store.dispatchOpenUrl(topUpUrl)
|
||||
} else {
|
||||
store.dispatch(WalletAction.TradeCryptoAction.Buy(checkUserLocation = false))
|
||||
}
|
||||
dismiss()
|
||||
}
|
||||
binding?.btnNo?.setOnClickListener {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue