Updated on 2026-08-14
This commit is contained in:
parent
1f80755686
commit
ab6346fc62
15 changed files with 492 additions and 197 deletions
|
|
@ -8,18 +8,26 @@ import com.tangem.tap.domain.TapError
|
|||
import com.tangem.tap.domain.extensions.amountToCreateAccount
|
||||
import com.tangem.tap.domain.getFirstToken
|
||||
import com.tangem.tap.domain.topup.TradeCryptoHelper
|
||||
import com.tangem.tap.features.demo.isDemoWallet
|
||||
import com.tangem.tap.features.wallet.redux.AddressData
|
||||
import com.tangem.tap.features.wallet.redux.reducers.createAddressesData
|
||||
import com.tangem.tap.network.NetworkConnectivity
|
||||
import com.tangem.tap.store
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
suspend fun WalletManager.safeUpdate(): Result<Wallet> = try {
|
||||
update()
|
||||
Result.Success(wallet)
|
||||
if (isDemoWallet()) {
|
||||
Result.Success(wallet)
|
||||
} else {
|
||||
update()
|
||||
Result.Success(wallet)
|
||||
}
|
||||
} catch (exception: Exception) {
|
||||
Timber.e(exception)
|
||||
|
||||
if (!NetworkConnectivity.getInstance().isOnlineOrConnecting()) {
|
||||
Result.Failure(TapError.NoInternetConnection)
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -10,9 +10,11 @@ import com.tangem.tap.currenciesRepository
|
|||
import com.tangem.tap.domain.TapWorkarounds.isStart2Coin
|
||||
import com.tangem.tap.domain.TapWorkarounds.isTestCard
|
||||
import com.tangem.tap.domain.configurable.config.ConfigManager
|
||||
import com.tangem.tap.domain.extensions.*
|
||||
import com.tangem.tap.domain.extensions.makePrimaryWalletManager
|
||||
import com.tangem.tap.domain.extensions.makeWalletManagersForApp
|
||||
import com.tangem.tap.domain.tasks.product.ScanResponse
|
||||
import com.tangem.tap.domain.tokens.CardCurrencies
|
||||
import com.tangem.tap.features.demo.isDemoCard
|
||||
import com.tangem.tap.features.wallet.redux.Currency
|
||||
import com.tangem.tap.features.wallet.redux.WalletAction
|
||||
import com.tangem.tap.network.NetworkConnectivity
|
||||
|
|
@ -207,6 +209,9 @@ class TapWalletManager {
|
|||
data.getBlockchain() == Blockchain.Unknown && !data.card.isMultiwalletAllowed -> {
|
||||
WalletAction.LoadData.Failure(TapError.UnknownBlockchain)
|
||||
}
|
||||
data.isDemoCard() -> {
|
||||
return null
|
||||
}
|
||||
data.card.wallets.isEmpty() -> {
|
||||
WalletAction.EmptyWallet
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import com.tangem.wallet.R
|
|||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
class WarningMessagesManager(
|
||||
private val warningLoader: RemoteWarningLoader,
|
||||
private val warningLoader: RemoteWarningLoader,
|
||||
) {
|
||||
|
||||
private val warningsList: MutableList<WarningMessage> = mutableListOf()
|
||||
|
|
@ -33,15 +33,15 @@ class WarningMessagesManager(
|
|||
|
||||
fun getWarnings(location: WarningMessage.Location, forBlockchains: List<Blockchain> = emptyList()): List<WarningMessage> {
|
||||
return warningsList
|
||||
.filter { !it.isHidden && it.location.contains(location) }
|
||||
.filter {
|
||||
val list = it.blockchainList
|
||||
when {
|
||||
list == null -> true
|
||||
list.containsAny(forBlockchains) -> true
|
||||
else -> false
|
||||
}
|
||||
.filter { !it.isHidden && it.location.contains(location) }
|
||||
.filter {
|
||||
val list = it.blockchainList
|
||||
when {
|
||||
list == null -> true
|
||||
list.containsAny(forBlockchains) -> true
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun hideWarning(warning: WarningMessage): Boolean {
|
||||
|
|
@ -49,7 +49,7 @@ class WarningMessagesManager(
|
|||
return when {
|
||||
foundWarning == null -> false
|
||||
foundWarning.type == WarningMessage.Type.Temporary
|
||||
|| foundWarning.type == WarningMessage.Type.AppRating -> {
|
||||
|| foundWarning.type == WarningMessage.Type.AppRating -> {
|
||||
if (foundWarning.isHidden) {
|
||||
false
|
||||
} else {
|
||||
|
|
@ -80,32 +80,32 @@ class WarningMessagesManager(
|
|||
|
||||
companion object {
|
||||
fun devCardWarning(): WarningMessage = WarningMessage(
|
||||
"",
|
||||
"",
|
||||
type = WarningMessage.Type.Permanent,
|
||||
priority = WarningMessage.Priority.Critical,
|
||||
listOf(WarningMessage.Location.MainScreen),
|
||||
null,
|
||||
R.string.alert_title,
|
||||
R.string.alert_developer_card,
|
||||
WarningMessage.Origin.Local
|
||||
"",
|
||||
"",
|
||||
type = WarningMessage.Type.Permanent,
|
||||
priority = WarningMessage.Priority.Critical,
|
||||
listOf(WarningMessage.Location.MainScreen),
|
||||
null,
|
||||
R.string.alert_title,
|
||||
R.string.alert_developer_card,
|
||||
WarningMessage.Origin.Local
|
||||
)
|
||||
|
||||
fun alreadySignedHashesWarning(): WarningMessage = WarningMessage(
|
||||
"",
|
||||
"",
|
||||
type = WarningMessage.Type.Temporary,
|
||||
priority = WarningMessage.Priority.Info,
|
||||
listOf(WarningMessage.Location.MainScreen),
|
||||
null,
|
||||
R.string.alert_title,
|
||||
R.string.alert_card_signed_transactions,
|
||||
WarningMessage.Origin.Local
|
||||
"",
|
||||
"",
|
||||
type = WarningMessage.Type.Temporary,
|
||||
priority = WarningMessage.Priority.Info,
|
||||
listOf(WarningMessage.Location.MainScreen),
|
||||
null,
|
||||
R.string.alert_title,
|
||||
R.string.alert_card_signed_transactions,
|
||||
WarningMessage.Origin.Local
|
||||
)
|
||||
|
||||
fun signedHashesMultiWalletWarning(): WarningMessage = WarningMessage(
|
||||
title = "",
|
||||
message = "",
|
||||
message = "",
|
||||
type = WarningMessage.Type.Temporary,
|
||||
priority = WarningMessage.Priority.Info,
|
||||
location = listOf(WarningMessage.Location.MainScreen),
|
||||
|
|
@ -117,15 +117,15 @@ class WarningMessagesManager(
|
|||
)
|
||||
|
||||
fun appRatingWarning(): WarningMessage = WarningMessage(
|
||||
"",
|
||||
"",
|
||||
WarningMessage.Type.AppRating,
|
||||
WarningMessage.Priority.Info,
|
||||
listOf(WarningMessage.Location.MainScreen),
|
||||
null,
|
||||
R.string.warning_rate_app_title,
|
||||
R.string.warning_rate_app_message,
|
||||
WarningMessage.Origin.Local
|
||||
"",
|
||||
"",
|
||||
WarningMessage.Type.AppRating,
|
||||
WarningMessage.Priority.Info,
|
||||
listOf(WarningMessage.Location.MainScreen),
|
||||
null,
|
||||
R.string.warning_rate_app_title,
|
||||
R.string.warning_rate_app_message,
|
||||
WarningMessage.Origin.Local
|
||||
)
|
||||
|
||||
fun isAlreadySignedHashesWarning(warning: WarningMessage): Boolean {
|
||||
|
|
@ -133,15 +133,15 @@ class WarningMessagesManager(
|
|||
}
|
||||
|
||||
fun onlineVerificationFailed(): WarningMessage = WarningMessage(
|
||||
"",
|
||||
"",
|
||||
type = WarningMessage.Type.Permanent,
|
||||
priority = WarningMessage.Priority.Critical,
|
||||
listOf(WarningMessage.Location.MainScreen),
|
||||
null,
|
||||
R.string.warning_failed_to_verify_card_title,
|
||||
R.string.warning_failed_to_verify_card_message,
|
||||
WarningMessage.Origin.Local
|
||||
"",
|
||||
"",
|
||||
type = WarningMessage.Type.Permanent,
|
||||
priority = WarningMessage.Priority.Critical,
|
||||
listOf(WarningMessage.Location.MainScreen),
|
||||
null,
|
||||
R.string.warning_failed_to_verify_card_title,
|
||||
R.string.warning_failed_to_verify_card_message,
|
||||
WarningMessage.Origin.Local
|
||||
)
|
||||
|
||||
fun remainingSignaturesNotEnough(remainingSignatures: Int): WarningMessage = WarningMessage(
|
||||
|
|
@ -169,6 +169,18 @@ class WarningMessagesManager(
|
|||
WarningMessage.Origin.Local
|
||||
)
|
||||
|
||||
fun demoCardWarning(): WarningMessage = WarningMessage(
|
||||
"",
|
||||
"",
|
||||
type = WarningMessage.Type.Permanent,
|
||||
priority = WarningMessage.Priority.Critical,
|
||||
listOf(WarningMessage.Location.MainScreen),
|
||||
null,
|
||||
R.string.alert_title,
|
||||
R.string.alert_demo_message,
|
||||
WarningMessage.Origin.Local
|
||||
)
|
||||
|
||||
const val REMAINING_SIGNATURES_WARNING = 10
|
||||
}
|
||||
}
|
||||
|
|
@ -13,9 +13,11 @@ import com.tangem.tap.common.extensions.appendIf
|
|||
import com.tangem.tap.common.extensions.readJsonFileToString
|
||||
import com.tangem.tap.domain.extensions.getCustomIconUrl
|
||||
import com.tangem.tap.domain.extensions.setCustomIconUrl
|
||||
import com.tangem.tap.features.demo.DemoHelper
|
||||
import com.tangem.tap.network.createMoshi
|
||||
|
||||
class CurrenciesRepository(val context: Application) {
|
||||
open class CurrenciesRepository(val context: Application) {
|
||||
|
||||
private val moshi = createMoshi()
|
||||
private val blockchainsAdapter: JsonAdapter<List<Blockchain>> = moshi.adapter(
|
||||
Types.newParameterizedType(List::class.java, Blockchain::class.java)
|
||||
|
|
@ -28,10 +30,13 @@ class CurrenciesRepository(val context: Application) {
|
|||
)
|
||||
|
||||
fun loadCardCurrencies(cardId: String): CardCurrencies? {
|
||||
val blockchains = loadSavedBlockchains(cardId)
|
||||
val blockchains = loadSavedBlockchains(cardId).toMutableSet()
|
||||
if (DemoHelper.isDemoCardId(cardId)) {
|
||||
blockchains.addAll(DemoHelper.config.demoBlockchains)
|
||||
}
|
||||
if (blockchains.isEmpty()) return null
|
||||
|
||||
return CardCurrencies(loadSavedTokens(cardId), blockchains)
|
||||
return CardCurrencies(loadSavedTokens(cardId), blockchains.toList())
|
||||
}
|
||||
|
||||
fun saveCardCurrencies(cardId: String, currencies: CardCurrencies) {
|
||||
|
|
|
|||
154
app/src/main/java/com/tangem/tap/features/demo/DemoHelper.kt
Normal file
154
app/src/main/java/com/tangem/tap/features/demo/DemoHelper.kt
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
package com.tangem.tap.features.demo
|
||||
|
||||
import com.tangem.blockchain.common.*
|
||||
import com.tangem.blockchain.extensions.Result
|
||||
import com.tangem.blockchain.extensions.SimpleResult
|
||||
import com.tangem.tap.common.extensions.dispatchNotification
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
import com.tangem.tap.domain.tasks.product.ScanResponse
|
||||
import com.tangem.tap.features.details.redux.walletconnect.WalletConnectAction
|
||||
import com.tangem.tap.features.onboarding.products.wallet.redux.BackupAction
|
||||
import com.tangem.tap.features.wallet.redux.WalletAction
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.wallet.BuildConfig
|
||||
import com.tangem.wallet.R
|
||||
import org.rekotlin.Action
|
||||
import java.math.BigDecimal
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
interface DemoMiddleware {
|
||||
fun tryHandle(config: DemoConfig, scanResponse: ScanResponse, action: Action): Boolean
|
||||
}
|
||||
|
||||
object DemoHelper {
|
||||
val config = DemoConfig()
|
||||
|
||||
private val demoMiddlewares = listOf(
|
||||
DemoOnboardingNoteMiddleware(),
|
||||
)
|
||||
|
||||
private val disabledActionFeatures = listOf(
|
||||
WalletConnectAction.StartWalletConnect::class.java,
|
||||
WalletAction.TradeCryptoAction.Buy::class.java,
|
||||
WalletAction.TradeCryptoAction.Sell::class.java,
|
||||
BackupAction.StartBackup::class.java,
|
||||
WalletAction.ExploreAddress::class.java
|
||||
)
|
||||
|
||||
fun isDemoCard(scanResponse: ScanResponse): Boolean = isDemoCardId(scanResponse.card.cardId)
|
||||
|
||||
fun isDemoCardId(cardId: String): Boolean = config.isDemoCardId(cardId)
|
||||
|
||||
fun tryHandle(appState: () -> AppState?, action: Action): Boolean {
|
||||
val scanResponse = getScanResponse(appState) ?: return false
|
||||
if (!scanResponse.isDemoCard()) return false
|
||||
|
||||
demoMiddlewares.forEach {
|
||||
if (it.tryHandle(config, scanResponse, action)) return true
|
||||
}
|
||||
|
||||
disabledActionFeatures.firstOrNull { it == action::class.java }?.let {
|
||||
store.dispatchNotification(R.string.alert_demo_feature_disabled)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
fun injectDemoBalance(walletManager: WalletManager?) {
|
||||
val manager = walletManager ?: return
|
||||
|
||||
val blockchain = walletManager.wallet.blockchain
|
||||
val amount = config.getBalance(blockchain)
|
||||
manager.wallet.setAmount(amount)
|
||||
}
|
||||
|
||||
private fun getScanResponse(appState: () -> AppState?): ScanResponse? {
|
||||
val state = appState() ?: return null
|
||||
|
||||
return state.globalState.onboardingState.onboardingManager?.scanResponse
|
||||
?: state.globalState.scanResponse
|
||||
}
|
||||
}
|
||||
|
||||
class DemoConfig {
|
||||
|
||||
val demoBlockchains = listOf(
|
||||
Blockchain.Bitcoin,
|
||||
Blockchain.Ethereum,
|
||||
Blockchain.XRP,
|
||||
Blockchain.Dogecoin,
|
||||
Blockchain.Solana,
|
||||
)
|
||||
|
||||
val demoCardIds: List<String> by lazy {
|
||||
val demoIds = (releaseDemoCardIds + testDemoCardIds).toMutableList()
|
||||
if (BuildConfig.DEBUG) demoIds.addAll(debugTestDemoCardIds)
|
||||
|
||||
return@lazy demoIds
|
||||
}
|
||||
|
||||
private val walletBalances: Map<Blockchain, Amount> = mapOf(
|
||||
Blockchain.Bitcoin to Amount(0.028.toBigDecimal(), Blockchain.Bitcoin),
|
||||
Blockchain.Ethereum to Amount(0.2311.toBigDecimal(), Blockchain.Ethereum),
|
||||
Blockchain.XRP to Amount(1248.56.toBigDecimal(), Blockchain.XRP),
|
||||
Blockchain.Dogecoin to Amount(1450.025.toBigDecimal(), Blockchain.Dogecoin),
|
||||
Blockchain.Solana to Amount(13.246.toBigDecimal(), Blockchain.Solana),
|
||||
)
|
||||
|
||||
fun isDemoCardId(cardId: String): Boolean = demoCardIds.contains(cardId)
|
||||
|
||||
fun getBalance(blockchain: Blockchain): Amount = walletBalances[blockchain]?.copy()
|
||||
?: Amount(BigDecimal.ZERO, blockchain).copy()
|
||||
|
||||
private val releaseDemoCardIds = mutableListOf<String>(
|
||||
|
||||
)
|
||||
|
||||
private val testDemoCardIds = listOf(
|
||||
"FB30000000000176",
|
||||
"FB20000000000186",
|
||||
"FB10000000000196",
|
||||
)
|
||||
|
||||
private val debugTestDemoCardIds = listOf(
|
||||
"AB06000000018575", // Note XRP
|
||||
"AB04000000011036", // Note Doge
|
||||
"AB01000000045060", // Note BTC
|
||||
"AB02000000045028", // Note ETH
|
||||
"AC01000000200003", // Wallet 4.52
|
||||
"AC79000000000004", // Wallet 4.46
|
||||
)
|
||||
}
|
||||
|
||||
class DemoTransactionSender(
|
||||
private val walletManager: WalletManager,
|
||||
private val sender: TransactionSender = walletManager as TransactionSender
|
||||
) : TransactionSender {
|
||||
|
||||
override suspend fun getFee(amount: Amount, destination: String): Result<List<Amount>> =
|
||||
sender.getFee(amount, destination)
|
||||
|
||||
override suspend fun send(transactionData: TransactionData, signer: TransactionSigner): SimpleResult {
|
||||
val dataToSign = randomString(32).toByteArray()
|
||||
val signerResponse = signer.sign(dataToSign, walletManager.wallet.cardId, walletManager.wallet.publicKey)
|
||||
return SimpleResult.Failure(Exception(ID))
|
||||
}
|
||||
|
||||
private fun randomInt(from: Int, to: Int): Int = kotlin.random.Random.nextInt(from, to)
|
||||
|
||||
private fun randomString(length: Int): String {
|
||||
val charPool: List<Char> = ('a'..'z') + ('A'..'Z') + ('0'..'9')
|
||||
return (1..length)
|
||||
.map { randomInt(0, charPool.size) }
|
||||
.map(charPool::get)
|
||||
.joinToString("")
|
||||
}
|
||||
|
||||
companion object{
|
||||
val ID = DemoTransactionSender::class.java.simpleName
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
package com.tangem.tap.features.demo
|
||||
|
||||
import com.tangem.common.extensions.guard
|
||||
import com.tangem.tap.common.extensions.withMainContext
|
||||
import com.tangem.tap.domain.extensions.makePrimaryWalletManager
|
||||
import com.tangem.tap.domain.tasks.product.ScanResponse
|
||||
import com.tangem.tap.features.onboarding.products.note.redux.OnboardingNoteAction
|
||||
import com.tangem.tap.features.wallet.redux.Currency
|
||||
import com.tangem.tap.features.wallet.redux.ProgressState
|
||||
import com.tangem.tap.scope
|
||||
import com.tangem.tap.store
|
||||
import kotlinx.coroutines.launch
|
||||
import org.rekotlin.Action
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal class DemoOnboardingNoteMiddleware : DemoMiddleware {
|
||||
|
||||
override fun tryHandle(config: DemoConfig, scanResponse: ScanResponse, action: Action): Boolean {
|
||||
val globalState = store.state.globalState
|
||||
val noteState = store.state.onboardingNoteState
|
||||
|
||||
when (action) {
|
||||
is OnboardingNoteAction.Balance.Update -> {
|
||||
val walletManager = if (noteState.walletManager != null) {
|
||||
noteState.walletManager
|
||||
} else {
|
||||
val wmFactory = globalState.tapWalletManager.walletManagerFactory
|
||||
val walletManager = wmFactory.makePrimaryWalletManager(scanResponse).guard {
|
||||
return false
|
||||
}
|
||||
store.dispatch(OnboardingNoteAction.SetWalletManager(walletManager))
|
||||
walletManager
|
||||
}
|
||||
val balanceAmount = config.getBalance(walletManager.wallet.blockchain)
|
||||
val loadedBalance = noteState.walletBalance.copy(
|
||||
value = balanceAmount.value!!,
|
||||
currency = Currency.Blockchain(walletManager.wallet.blockchain),
|
||||
state = ProgressState.Done,
|
||||
error = null,
|
||||
criticalError = null
|
||||
)
|
||||
walletManager.wallet.setAmount(balanceAmount)
|
||||
|
||||
scope.launch {
|
||||
withMainContext {
|
||||
store.dispatch(OnboardingNoteAction.Balance.Set(loadedBalance))
|
||||
store.dispatch(OnboardingNoteAction.Balance.SetCriticalError(loadedBalance.criticalError))
|
||||
store.dispatch(OnboardingNoteAction.Balance.SetNonCriticalError(loadedBalance.error))
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
12
app/src/main/java/com/tangem/tap/features/demo/Extentions.kt
Normal file
12
app/src/main/java/com/tangem/tap/features/demo/Extentions.kt
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
package com.tangem.tap.features.demo
|
||||
|
||||
import com.tangem.blockchain.common.Wallet
|
||||
import com.tangem.blockchain.common.WalletManager
|
||||
import com.tangem.tap.domain.tasks.product.ScanResponse
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
fun ScanResponse.isDemoCard(): Boolean = DemoHelper.isDemoCardId(card.cardId)
|
||||
fun WalletManager.isDemoWallet(): Boolean = DemoHelper.isDemoCardId(wallet.cardId)
|
||||
fun Wallet.isDemoWallet(): Boolean = DemoHelper.isDemoCardId(cardId)
|
||||
|
|
@ -17,9 +17,11 @@ import com.tangem.tap.domain.tasks.product.ScanResponse
|
|||
import com.tangem.tap.domain.walletconnect.BnbHelper
|
||||
import com.tangem.tap.domain.walletconnect.WalletConnectManager
|
||||
import com.tangem.tap.domain.walletconnect.WalletConnectNetworkUtils
|
||||
import com.tangem.tap.features.demo.DemoHelper
|
||||
import com.tangem.tap.features.wallet.redux.WalletAction
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.wallet.R
|
||||
import org.rekotlin.Action
|
||||
import org.rekotlin.Middleware
|
||||
|
||||
class WalletConnectMiddleware {
|
||||
|
|
@ -28,138 +30,131 @@ class WalletConnectMiddleware {
|
|||
val walletConnectMiddleware: Middleware<AppState> = { dispatch, state ->
|
||||
{ next ->
|
||||
{ action ->
|
||||
when (action) {
|
||||
handle(state, action)
|
||||
next(action)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
is WalletConnectAction.RestoreSessions -> {
|
||||
walletConnectManager.restoreSessions()
|
||||
}
|
||||
private fun handle(state: () -> AppState?, action: Action) {
|
||||
if (DemoHelper.tryHandle(state, action)) return
|
||||
|
||||
is WalletConnectAction.HandleDeepLink -> {
|
||||
if (!action.wcUri.isNullOrBlank()) {
|
||||
if (WalletConnectManager.isCorrectWcUri(action.wcUri)) {
|
||||
store.dispatchOnMain(WalletConnectAction.OpenSession(action.wcUri))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
is WalletConnectAction.StartWalletConnect -> {
|
||||
val uri = action.activity.getFromClipboard()?.toString()
|
||||
if (uri != null && WalletConnectManager.isCorrectWcUri(uri)) {
|
||||
store.dispatchOnMain(WalletConnectAction.ShowClipboardOrScanQrDialog(uri))
|
||||
} else {
|
||||
store.dispatchOnMain(NavigationAction.NavigateTo(AppScreen.QrScan))
|
||||
}
|
||||
}
|
||||
|
||||
is WalletConnectAction.ShowClipboardOrScanQrDialog -> {
|
||||
store.dispatchOnMain(
|
||||
GlobalAction.ShowDialog(
|
||||
WalletConnectDialog.ClipboardOrScanQr(
|
||||
action.wcUri
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
is WalletConnectAction.OpeningSessionTimeout -> {
|
||||
store.dispatchOnMain(GlobalAction.ShowDialog(WalletConnectDialog.SessionTimeout))
|
||||
}
|
||||
|
||||
is WalletConnectAction.FailureEstablishingSession -> {
|
||||
if (action.session != null) {
|
||||
walletConnectManager.disconnect(action.session)
|
||||
}
|
||||
}
|
||||
|
||||
is WalletConnectAction.UnsupportedCard -> {
|
||||
store.dispatchOnMain(GlobalAction.ShowDialog(WalletConnectDialog.UnsupportedCard))
|
||||
}
|
||||
|
||||
is WalletConnectAction.OpenSession -> {
|
||||
walletConnectManager.connect(
|
||||
wcUri = action.wcUri,
|
||||
)
|
||||
}
|
||||
|
||||
is WalletConnectAction.RefuseOpeningSession -> {
|
||||
store.dispatch(
|
||||
GlobalAction.ShowDialog(
|
||||
WalletConnectDialog.OpeningSessionRejected
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
is WalletConnectAction.ScanCard -> {
|
||||
scanCard(action.session, action.chainId)
|
||||
}
|
||||
|
||||
is WalletConnectAction.ApproveSession -> {
|
||||
walletConnectManager.approve(action.session)
|
||||
}
|
||||
|
||||
is WalletConnectAction.DisconnectSession -> {
|
||||
walletConnectManager.disconnect(action.session)
|
||||
}
|
||||
|
||||
is WalletConnectAction.HandleTransactionRequest -> {
|
||||
walletConnectManager.handleTransactionRequest(
|
||||
transaction = action.transaction,
|
||||
session = action.session,
|
||||
id = action.id,
|
||||
type = action.type
|
||||
)
|
||||
}
|
||||
is WalletConnectAction.HandlePersonalSignRequest -> {
|
||||
walletConnectManager.handlePersonalSignRequest(
|
||||
message = action.message,
|
||||
session = action.session,
|
||||
id = action.id
|
||||
)
|
||||
}
|
||||
is WalletConnectAction.RejectRequest -> {
|
||||
walletConnectManager.rejectRequest(action.session, action.id)
|
||||
}
|
||||
is WalletConnectAction.SendTransaction -> {
|
||||
walletConnectManager.completeTransaction(action.session)
|
||||
}
|
||||
is WalletConnectAction.SignMessage -> {
|
||||
walletConnectManager.sendSignedMessage(action.session)
|
||||
}
|
||||
is WalletConnectAction.BinanceTransaction.Trade -> {
|
||||
val messageData = BnbHelper.createMessageData(action.order)
|
||||
store.dispatchOnMain(
|
||||
GlobalAction.ShowDialog(
|
||||
WalletConnectDialog.BnbTransactionDialog(
|
||||
data = messageData,
|
||||
session = action.sessionData.session,
|
||||
sessionId = action.id,
|
||||
cardId = action.sessionData.wallet.cardId,
|
||||
dAppName = action.sessionData.peerMeta.name
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
is WalletConnectAction.BinanceTransaction.Transfer -> {
|
||||
val messageData = BnbHelper.createMessageData(action.order)
|
||||
store.dispatchOnMain(
|
||||
GlobalAction.ShowDialog(
|
||||
WalletConnectDialog.BnbTransactionDialog(
|
||||
data = messageData,
|
||||
session = action.sessionData.session,
|
||||
sessionId = action.id,
|
||||
cardId = action.sessionData.wallet.cardId,
|
||||
dAppName = action.sessionData.peerMeta.name
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
is WalletConnectAction.BinanceTransaction.Sign -> {
|
||||
walletConnectManager.signBnb(
|
||||
action.id, action.data, action.sessionData
|
||||
)
|
||||
when (action) {
|
||||
is WalletConnectAction.RestoreSessions -> {
|
||||
walletConnectManager.restoreSessions()
|
||||
}
|
||||
is WalletConnectAction.HandleDeepLink -> {
|
||||
if (!action.wcUri.isNullOrBlank()) {
|
||||
if (WalletConnectManager.isCorrectWcUri(action.wcUri)) {
|
||||
store.dispatchOnMain(WalletConnectAction.OpenSession(action.wcUri))
|
||||
}
|
||||
}
|
||||
next(action)
|
||||
}
|
||||
is WalletConnectAction.StartWalletConnect -> {
|
||||
val uri = action.activity.getFromClipboard()?.toString()
|
||||
if (uri != null && WalletConnectManager.isCorrectWcUri(uri)) {
|
||||
store.dispatchOnMain(WalletConnectAction.ShowClipboardOrScanQrDialog(uri))
|
||||
} else {
|
||||
store.dispatchOnMain(NavigationAction.NavigateTo(AppScreen.QrScan))
|
||||
}
|
||||
}
|
||||
is WalletConnectAction.ShowClipboardOrScanQrDialog -> {
|
||||
store.dispatchOnMain(
|
||||
GlobalAction.ShowDialog(
|
||||
WalletConnectDialog.ClipboardOrScanQr(
|
||||
action.wcUri
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
is WalletConnectAction.OpeningSessionTimeout -> {
|
||||
store.dispatchOnMain(GlobalAction.ShowDialog(WalletConnectDialog.SessionTimeout))
|
||||
}
|
||||
is WalletConnectAction.FailureEstablishingSession -> {
|
||||
if (action.session != null) {
|
||||
walletConnectManager.disconnect(action.session)
|
||||
}
|
||||
}
|
||||
is WalletConnectAction.UnsupportedCard -> {
|
||||
store.dispatchOnMain(GlobalAction.ShowDialog(WalletConnectDialog.UnsupportedCard))
|
||||
}
|
||||
is WalletConnectAction.OpenSession -> {
|
||||
walletConnectManager.connect(
|
||||
wcUri = action.wcUri,
|
||||
)
|
||||
}
|
||||
is WalletConnectAction.RefuseOpeningSession -> {
|
||||
store.dispatch(
|
||||
GlobalAction.ShowDialog(
|
||||
WalletConnectDialog.OpeningSessionRejected
|
||||
)
|
||||
)
|
||||
}
|
||||
is WalletConnectAction.ScanCard -> {
|
||||
scanCard(action.session, action.chainId)
|
||||
}
|
||||
is WalletConnectAction.ApproveSession -> {
|
||||
walletConnectManager.approve(action.session)
|
||||
}
|
||||
is WalletConnectAction.DisconnectSession -> {
|
||||
walletConnectManager.disconnect(action.session)
|
||||
}
|
||||
is WalletConnectAction.HandleTransactionRequest -> {
|
||||
walletConnectManager.handleTransactionRequest(
|
||||
transaction = action.transaction,
|
||||
session = action.session,
|
||||
id = action.id,
|
||||
type = action.type
|
||||
)
|
||||
}
|
||||
is WalletConnectAction.HandlePersonalSignRequest -> {
|
||||
walletConnectManager.handlePersonalSignRequest(
|
||||
message = action.message,
|
||||
session = action.session,
|
||||
id = action.id
|
||||
)
|
||||
}
|
||||
is WalletConnectAction.RejectRequest -> {
|
||||
walletConnectManager.rejectRequest(action.session, action.id)
|
||||
}
|
||||
is WalletConnectAction.SendTransaction -> {
|
||||
walletConnectManager.completeTransaction(action.session)
|
||||
}
|
||||
is WalletConnectAction.SignMessage -> {
|
||||
walletConnectManager.sendSignedMessage(action.session)
|
||||
}
|
||||
is WalletConnectAction.BinanceTransaction.Trade -> {
|
||||
val messageData = BnbHelper.createMessageData(action.order)
|
||||
store.dispatchOnMain(
|
||||
GlobalAction.ShowDialog(
|
||||
WalletConnectDialog.BnbTransactionDialog(
|
||||
data = messageData,
|
||||
session = action.sessionData.session,
|
||||
sessionId = action.id,
|
||||
cardId = action.sessionData.wallet.cardId,
|
||||
dAppName = action.sessionData.peerMeta.name
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
is WalletConnectAction.BinanceTransaction.Transfer -> {
|
||||
val messageData = BnbHelper.createMessageData(action.order)
|
||||
store.dispatchOnMain(
|
||||
GlobalAction.ShowDialog(
|
||||
WalletConnectDialog.BnbTransactionDialog(
|
||||
data = messageData,
|
||||
session = action.sessionData.session,
|
||||
sessionId = action.id,
|
||||
cardId = action.sessionData.wallet.cardId,
|
||||
dAppName = action.sessionData.peerMeta.name
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
is WalletConnectAction.BinanceTransaction.Sign -> {
|
||||
walletConnectManager.signBnb(
|
||||
action.id, action.data, action.sessionData
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -190,9 +185,9 @@ class WalletConnectMiddleware {
|
|||
}
|
||||
|
||||
val walletManager = getWalletManager(scanResponse, blockchain).guard {
|
||||
store.dispatchOnMain(WalletConnectAction.FailureEstablishingSession(null))
|
||||
return
|
||||
}
|
||||
store.dispatchOnMain(WalletConnectAction.FailureEstablishingSession(null))
|
||||
return
|
||||
}
|
||||
|
||||
val wallet = walletManager.wallet
|
||||
val derivedKey =
|
||||
|
|
@ -227,7 +222,7 @@ class WalletConnectMiddleware {
|
|||
): WalletManager? {
|
||||
val card = scanResponse.card
|
||||
val factory = store.state.globalState.tapWalletManager.walletManagerFactory
|
||||
val blockchainToMake = if (blockchain == Blockchain.Ethereum && card.isTestCard) {
|
||||
val blockchainToMake = if (blockchain == Blockchain.Ethereum && card.isTestCard) {
|
||||
Blockchain.EthereumTestnet
|
||||
} else {
|
||||
blockchain
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import com.tangem.tap.domain.DELAY_SDK_DIALOG_CLOSE
|
|||
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.wallet.redux.Currency
|
||||
import com.tangem.tap.features.wallet.redux.ProgressState
|
||||
import com.tangem.tap.scope
|
||||
|
|
@ -33,14 +34,16 @@ class OnboardingNoteMiddleware {
|
|||
private val onboardingNoteMiddleware: Middleware<AppState> = { dispatch, state ->
|
||||
{ next ->
|
||||
{ action ->
|
||||
handleNoteAction(action, dispatch)
|
||||
handleNoteAction(state, action, dispatch)
|
||||
next(action)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleNoteAction(action: Action, dispatch: DispatchFunction) {
|
||||
private fun handleNoteAction(appState: () -> AppState?, action: Action, dispatch: DispatchFunction) {
|
||||
if (action !is OnboardingNoteAction) return
|
||||
if (DemoHelper.tryHandle(appState, action)) return
|
||||
|
||||
val globalState = store.state.globalState
|
||||
val onboardingManager = globalState.onboardingState.onboardingManager ?: return
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import com.tangem.tap.common.redux.navigation.AppScreen
|
|||
import com.tangem.tap.common.redux.navigation.NavigationAction
|
||||
import com.tangem.tap.domain.extensions.hasWallets
|
||||
import com.tangem.tap.domain.tasks.product.ScanResponse
|
||||
import com.tangem.tap.features.demo.DemoHelper
|
||||
import com.tangem.tap.features.home.redux.HomeAction
|
||||
import com.tangem.tap.features.onboarding.products.wallet.redux.OnboardingWalletMiddleware.Companion.BUY_WALLET_URL
|
||||
import com.tangem.tap.features.wallet.redux.Artwork
|
||||
|
|
@ -164,14 +165,16 @@ class BackupMiddleware {
|
|||
val backupMiddleware: Middleware<AppState> = { dispatch, state ->
|
||||
{ next ->
|
||||
{ action ->
|
||||
if (action is BackupAction) handleBackupAction(action)
|
||||
if (action is BackupAction) handleBackupAction(state, action)
|
||||
next(action)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleBackupAction(action: BackupAction) {
|
||||
private fun handleBackupAction(appState: () -> AppState?, action: BackupAction) {
|
||||
if (DemoHelper.tryHandle(appState, action)) return
|
||||
|
||||
val backupState = store.state.onboardingWalletState.backupState
|
||||
|
||||
val globalState = store.state.globalState
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import com.tangem.tap.common.analytics.Analytics
|
|||
import com.tangem.tap.common.analytics.AnalyticsEvent
|
||||
import com.tangem.tap.common.analytics.AnalyticsParam
|
||||
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
|
||||
import com.tangem.tap.common.redux.navigation.NavigationAction
|
||||
|
|
@ -22,6 +23,8 @@ import com.tangem.tap.domain.TapError
|
|||
import com.tangem.tap.domain.TapWorkarounds.isStart2Coin
|
||||
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.isDemoWallet
|
||||
import com.tangem.tap.features.send.redux.*
|
||||
import com.tangem.tap.features.send.redux.FeeAction.RequestFee
|
||||
import com.tangem.tap.features.send.redux.states.ButtonState
|
||||
|
|
@ -32,6 +35,7 @@ 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.wallet.R
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
|
|
@ -164,9 +168,12 @@ private fun sendTransaction(
|
|||
)
|
||||
)
|
||||
}
|
||||
|
||||
val sendResult = try {
|
||||
(walletManager as TransactionSender).send(txData, signer)
|
||||
if (walletManager.isDemoWallet()) {
|
||||
DemoTransactionSender(walletManager).send(txData, signer)
|
||||
} else {
|
||||
(walletManager as TransactionSender).send(txData, signer)
|
||||
}
|
||||
} catch (ex: Exception) {
|
||||
FirebaseCrashlytics.getInstance().recordException(ex)
|
||||
delay(DELAY_SDK_DIALOG_CLOSE)
|
||||
|
|
@ -238,6 +245,12 @@ private fun sendTransaction(
|
|||
message.contains("Target account is not created. To create account send 1+ XLM.") -> {
|
||||
dispatch(SendAction.SendError(TapError.XmlError.AssetAccountNotCreated))
|
||||
}
|
||||
message.contains(DemoTransactionSender.ID) -> {
|
||||
store.dispatchDialogShow(AppDialog.SimpleOkDialogRes(
|
||||
R.string.common_done,
|
||||
R.string.alert_demo_tx_send
|
||||
))
|
||||
}
|
||||
else -> {
|
||||
(sendResult.error as? TangemSdkError)?.let { error ->
|
||||
store.state.globalState.analyticsHandlers?.logCardSdkError(
|
||||
|
|
|
|||
|
|
@ -37,6 +37,9 @@ class MultiWalletMiddleware {
|
|||
is WalletAction.MultiWallet.AddWalletManagers -> {
|
||||
globalState.feedbackManager?.infoHolder?.setWalletsInfo(action.walletManagers)
|
||||
action.walletManagers.forEach { checkForRentWarning(it) }
|
||||
if (globalState.scanResponse?.isDemoCard() == true) {
|
||||
addDummyBalances(action.walletManagers)
|
||||
}
|
||||
}
|
||||
is WalletAction.MultiWallet.SelectWallet -> {
|
||||
if (action.walletData != null) {
|
||||
|
|
@ -167,6 +170,14 @@ class MultiWalletMiddleware {
|
|||
}
|
||||
}
|
||||
|
||||
private fun addDummyBalances(walletManagers: List<WalletManager>) {
|
||||
walletManagers.forEach {
|
||||
if (it.wallet.fundsAvailable(AmountType.Coin) == BigDecimal.ZERO) {
|
||||
DemoHelper.injectDemoBalance(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun addToken(token: Token, walletState: WalletState?, globalState: GlobalState?) {
|
||||
val scanResponse = globalState?.scanResponse ?: return
|
||||
|
||||
|
|
|
|||
|
|
@ -3,10 +3,12 @@ package com.tangem.tap.features.wallet.redux.middlewares
|
|||
import com.tangem.blockchain.blockchains.ethereum.EthereumWalletManager
|
||||
import com.tangem.blockchain.common.AmountType
|
||||
import com.tangem.tap.common.extensions.dispatchOnMain
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
import com.tangem.tap.common.redux.navigation.AppScreen
|
||||
import com.tangem.tap.common.redux.navigation.NavigationAction
|
||||
import com.tangem.tap.domain.topup.TopUpManager
|
||||
import com.tangem.tap.domain.topup.TradeCryptoHelper
|
||||
import com.tangem.tap.features.demo.DemoHelper
|
||||
import com.tangem.tap.features.send.redux.PrepareSendScreen
|
||||
import com.tangem.tap.features.send.redux.SendAction
|
||||
import com.tangem.tap.features.wallet.redux.Currency
|
||||
|
|
@ -18,7 +20,9 @@ import timber.log.Timber
|
|||
|
||||
|
||||
class TradeCryptoMiddleware {
|
||||
fun handle(action: WalletAction.TradeCryptoAction) {
|
||||
fun handle(state: () -> AppState?, action: WalletAction.TradeCryptoAction) {
|
||||
if (DemoHelper.tryHandle(state, action)) return
|
||||
|
||||
when (action) {
|
||||
is WalletAction.TradeCryptoAction.Buy -> startExchange(action)
|
||||
is WalletAction.TradeCryptoAction.Sell -> startExchange(action)
|
||||
|
|
|
|||
|
|
@ -3,13 +3,15 @@ package com.tangem.tap.features.wallet.redux.middlewares
|
|||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.tangem.blockchain.common.*
|
||||
import com.tangem.blockchain.common.Amount
|
||||
import com.tangem.blockchain.common.AmountType
|
||||
import com.tangem.blockchain.common.Wallet
|
||||
import com.tangem.blockchain.common.WalletManager
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.common.core.TangemSdkError
|
||||
import com.tangem.common.extensions.isZero
|
||||
import com.tangem.common.services.Result
|
||||
import com.tangem.operations.attestation.OnlineCardVerifier
|
||||
import com.tangem.tap.*
|
||||
import com.tangem.tap.common.analytics.Analytics
|
||||
import com.tangem.tap.common.extensions.*
|
||||
import com.tangem.tap.common.redux.AppDialog
|
||||
|
|
@ -18,10 +20,14 @@ import com.tangem.tap.common.redux.global.GlobalAction
|
|||
import com.tangem.tap.common.redux.navigation.AppScreen
|
||||
import com.tangem.tap.common.redux.navigation.NavigationAction
|
||||
import com.tangem.tap.domain.extensions.toSendableAmounts
|
||||
import com.tangem.tap.features.demo.DemoHelper
|
||||
import com.tangem.tap.features.home.redux.HomeAction
|
||||
import com.tangem.tap.features.send.redux.PrepareSendScreen
|
||||
import com.tangem.tap.features.wallet.redux.*
|
||||
import com.tangem.tap.network.NetworkStateChanged
|
||||
import com.tangem.tap.scope
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.tap.tangemSdkManager
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
import kotlinx.coroutines.launch
|
||||
|
|
@ -37,18 +43,20 @@ class WalletMiddleware {
|
|||
val walletMiddleware: Middleware<AppState> = { dispatch, state ->
|
||||
{ next ->
|
||||
{ action ->
|
||||
handleAction(action, dispatch)
|
||||
handleAction(state, action, dispatch)
|
||||
next(action)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleAction(action: Action, dispatch: DispatchFunction) {
|
||||
private fun handleAction(state: () -> AppState?, action: Action, dispatch: DispatchFunction) {
|
||||
if (DemoHelper.tryHandle(state, action)) return
|
||||
|
||||
val globalState = store.state.globalState
|
||||
val walletState = store.state.walletState
|
||||
|
||||
when (action) {
|
||||
is WalletAction.TradeCryptoAction -> tradeCryptoMiddleware.handle(action)
|
||||
is WalletAction.TradeCryptoAction -> tradeCryptoMiddleware.handle(state, action)
|
||||
is WalletAction.Warnings -> warningsMiddleware.handle(action, globalState)
|
||||
is WalletAction.MultiWallet -> multiWalletMiddleware.handle(action, walletState, globalState)
|
||||
is WalletAction.LoadWallet -> {
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import com.tangem.tap.domain.extensions.hasSignedHashes
|
|||
import com.tangem.tap.domain.extensions.remainingSignatures
|
||||
import com.tangem.tap.domain.isMultiwalletAllowed
|
||||
import com.tangem.tap.domain.tasks.product.ScanResponse
|
||||
import com.tangem.tap.features.demo.isDemoCard
|
||||
import com.tangem.tap.features.wallet.redux.WalletAction
|
||||
import com.tangem.tap.network.NetworkConnectivity
|
||||
import com.tangem.tap.preferencesStorage
|
||||
|
|
@ -99,6 +100,9 @@ class WarningsMiddleware {
|
|||
addWarningMessage(WarningMessagesManager.onlineVerificationFailed())
|
||||
}
|
||||
}
|
||||
if (scanResponse.isDemoCard()){
|
||||
addWarningMessage(WarningMessagesManager.demoCardWarning())
|
||||
}
|
||||
setWarningMessages()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue