Updated on 2026-08-14

This commit is contained in:
Tangem 2022-11-15 00:05:34 +05:00
commit 9630db2885
31 changed files with 589 additions and 389 deletions

View file

@ -152,7 +152,8 @@ class DialogManager : StoreSubscriber<GlobalState> {
primaryButtonRes = state.dialog.primaryButtonRes,
primaryButtonAction = state.dialog.onOk,
)
is WalletDialog.RussianCardholdersWarningDialog -> RussianCardholdersWarningBottomSheetDialog(context)
is WalletDialog.RussianCardholdersWarningDialog ->
RussianCardholdersWarningBottomSheetDialog(context, state.dialog.topUpUrl)
else -> null
}
dialog?.show()

View file

@ -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) }
@ -268,13 +271,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
}
@ -288,12 +291,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
}
@ -326,14 +329,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
}

View file

@ -127,17 +127,17 @@ 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 -> {
@ -151,7 +151,7 @@ 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,
@ -164,7 +164,7 @@ class WalletConnectSdkHelper {
walletPublicKey = data.walletManager.wallet.publicKey.seedKey,
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
@ -177,13 +177,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,
)
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()
@ -253,10 +253,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(

View file

@ -10,9 +10,9 @@ import com.tangem.tap.common.analytics.events.Onboarding
import com.tangem.tap.common.extensions.dispatchDebugErrorNotification
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.getTopUpUrl
import com.tangem.tap.common.extensions.onCardScanned
import com.tangem.tap.common.postUi
import com.tangem.tap.common.redux.AppDialog
@ -24,8 +24,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
@ -172,11 +174,16 @@ private fun handleNoteAction(appState: () -> AppState?, action: Action, dispatch
return
}
val topUpUrl = noteState.walletManager.getToUpUrl() ?: return
if (globalState.userCountryCode == RUSSIA_COUNTRY_CODE) {
store.dispatchOnMain(WalletAction.DialogAction.RussianCardholdersWarningDialog(topUpUrl))
return
}
val blockchain = walletManager.wallet.blockchain
val currencyType = AnalyticsParam.CurrencyType.Blockchain(blockchain)
Analytics.send(Onboarding.Topup.ButtonBuyCrypto(currencyType))
val topUpUrl = walletManager.getTopUpUrl() ?: return
store.dispatchOpenUrl(topUpUrl)
}
OnboardingNoteAction.Done -> {

View file

@ -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()
}

View file

@ -40,7 +40,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
}

View file

@ -38,7 +38,7 @@ class WalletDialogsMiddleware {
)
}
is WalletAction.DialogAction.RussianCardholdersWarningDialog -> {
store.dispatchDialogShow(WalletDialog.RussianCardholdersWarningDialog)
store.dispatchDialogShow(WalletDialog.RussianCardholdersWarningDialog(action.topUpUrl))
}
is WalletAction.DialogAction.Hide -> {
store.dispatchDialogHide()

View file

@ -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
}

View file

@ -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(

View file

@ -7,12 +7,16 @@ import com.google.android.material.bottomsheet.BottomSheetDialog
import com.tangem.tap.common.analytics.Analytics
import com.tangem.tap.common.analytics.events.Token
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
@ -32,7 +36,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 {