Updated on 2026-08-14

This commit is contained in:
Tangem 2022-11-12 03:46:02 +04:00
parent 4375e7687f
commit 0d993b5141
53 changed files with 430 additions and 356 deletions

View file

@ -1,10 +1,10 @@
package com.tangem.tap.features.demo
import com.tangem.common.card.Card
import com.tangem.domain.common.CardDTO
import com.tangem.domain.common.ScanResponse
/**
[REDACTED_AUTHOR]
*/
fun ScanResponse.isDemoCard(): Boolean = DemoHelper.isDemoCardId(card.cardId)
fun Card.isDemoCard(): Boolean = DemoHelper.isDemoCardId(cardId)
fun CardDTO.isDemoCard(): Boolean = DemoHelper.isDemoCardId(cardId)

View file

@ -1,7 +1,7 @@
package com.tangem.tap.features.details.redux
import com.tangem.blockchain.common.Wallet
import com.tangem.common.card.Card
import com.tangem.domain.common.CardDTO
import com.tangem.domain.common.ScanResponse
import com.tangem.tap.common.entities.FiatCurrency
import com.tangem.tap.domain.termsOfUse.CardTou
@ -30,7 +30,7 @@ sealed class DetailsAction : Action {
object ScanCard : DetailsAction()
data class PrepareCardSettingsData(val card: Card) : DetailsAction()
data class PrepareCardSettingsData(val card: CardDTO) : DetailsAction()
object ResetCardSettingsData : DetailsAction()
sealed class ManageSecurity : DetailsAction() {

View file

@ -3,6 +3,7 @@ package com.tangem.tap.features.details.redux
import com.tangem.common.CompletionResult
import com.tangem.common.core.TangemSdkError
import com.tangem.domain.common.TapWorkarounds.isTangemTwins
import com.tangem.domain.common.util.userWalletId
import com.tangem.tap.common.analytics.Analytics
import com.tangem.tap.common.analytics.events.AnalyticsParam
import com.tangem.tap.common.analytics.events.Settings
@ -13,7 +14,6 @@ import com.tangem.tap.common.redux.AppState
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.getUserWalletId
import com.tangem.tap.features.demo.DemoHelper
import com.tangem.tap.features.onboarding.products.twins.redux.CreateTwinWalletMode
import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsAction
@ -67,11 +67,12 @@ class DetailsMiddleware {
scope.launch {
when (val result = tangemSdkManager.scanCard()) {
is CompletionResult.Success -> {
val card = result.data
if (card.getUserWalletId() ==
store.state.globalState.scanResponse?.card?.getUserWalletId()
) {
store.dispatchOnMain(DetailsAction.PrepareCardSettingsData(card))
val scannedCard = result.data
val currentCardId = store.state.globalState.scanResponse?.card
?.userWalletId
?.stringValue
if (scannedCard.userWalletId.stringValue == currentCardId) {
store.dispatchOnMain(DetailsAction.PrepareCardSettingsData(scannedCard))
} else {
store.dispatchDialogShow(
AppDialog.SimpleOkDialogRes(
@ -81,8 +82,7 @@ class DetailsMiddleware {
)
}
}
is CompletionResult.Failure -> {
}
is CompletionResult.Failure -> Unit
}
}
}
@ -104,22 +104,20 @@ class DetailsMiddleware {
is DetailsAction.ResetToFactory.Proceed -> {
val card = store.state.detailsState.cardSettingsState?.card ?: return
scope.launch {
val result = tangemSdkManager.resetToFactorySettings(card)
when (result) {
when (val result = tangemSdkManager.resetToFactorySettings(card.cardId)) {
is CompletionResult.Success -> {
Analytics.send(Settings.CardSettings.FactoryResetFinished())
store.dispatchOnMain(NavigationAction.PopBackTo(AppScreen.Home))
}
is CompletionResult.Failure -> {
(result.error as? TangemSdkError)?.let { error ->
Analytics.send(Settings.CardSettings.FactoryResetFinished(error))
}
Analytics.send(Settings.CardSettings.FactoryResetFinished(error)) }
}
}
}
}
else -> { /* no-op */
}
else -> Unit
}
}
}
@ -156,8 +154,7 @@ class DetailsMiddleware {
}
store.dispatch(DetailsAction.ManageSecurity.SaveChanges.Failure)
}
else -> { /* no-op */
}
else -> Unit
}
}
}
@ -171,8 +168,7 @@ class DetailsMiddleware {
}
}
}
else -> { /* no-op */
}
else -> Unit
}
}
}
@ -186,4 +182,4 @@ class DetailsMiddleware {
}
}
}
}
}

View file

@ -1,6 +1,6 @@
package com.tangem.tap.features.details.redux
import com.tangem.common.card.Card
import com.tangem.domain.common.CardDTO
import com.tangem.domain.common.TapWorkarounds.isSaltPay
import com.tangem.domain.common.TapWorkarounds.isStart2Coin
import com.tangem.domain.common.TapWorkarounds.isTangemNote
@ -51,12 +51,12 @@ private fun handlePrepareScreen(
scanResponse = action.scanResponse,
wallets = action.wallets,
cardTermsOfUseUrl = action.cardTou.getUrl(action.scanResponse.card),
createBackupAllowed = action.scanResponse.card.backupStatus == Card.BackupStatus.NoBackup,
createBackupAllowed = action.scanResponse.card.backupStatus == CardDTO.BackupStatus.NoBackup,
appCurrency = store.state.globalState.appCurrency,
)
}
private fun handlePrepareCardSettingsScreen(card: Card, state: DetailsState): DetailsState {
private fun handlePrepareCardSettingsScreen(card: CardDTO, state: DetailsState): DetailsState {
val cardSettingsState = CardSettingsState(
cardInfo = card.toCardInfo(),
manageSecurityState = prepareSecurityOptions(card),
@ -66,14 +66,16 @@ private fun handlePrepareCardSettingsScreen(card: Card, state: DetailsState): De
return state.copy(cardSettingsState = cardSettingsState)
}
private fun prepareSecurityOptions(card: Card): ManageSecurityState {
private fun prepareSecurityOptions(card: CardDTO): ManageSecurityState {
val securityOption = when {
card.isAccessCodeSet -> {
SecurityOption.AccessCode
}
card.isPasscodeSet == true -> {
SecurityOption.PassCode
}
else -> {
SecurityOption.LongTap
}
@ -94,7 +96,7 @@ private fun prepareSecurityOptions(card: Card): ManageSecurityState {
)
}
private fun isResetToFactoryAllowedByCard(card: Card): Boolean {
private fun isResetToFactoryAllowedByCard(card: CardDTO): Boolean {
val notAllowedByAnyWallet = card.wallets.any { it.settings.isPermanent }
val notAllowedByCard = notAllowedByAnyWallet ||
(card.isWalletDataSupported && (!card.isTangemNote && !card.settings.isBackupAllowed)) ||
@ -114,7 +116,8 @@ private fun handleEraseWallet(
}
private fun handleSecurityAction(
action: DetailsAction.ManageSecurity, state: DetailsState,
action: DetailsAction.ManageSecurity,
state: DetailsState,
): DetailsState {
return when (action) {
is DetailsAction.ManageSecurity.SelectOption -> {
@ -144,7 +147,8 @@ private fun handleSecurityAction(
}
private fun handlePrivacyAction(
action: DetailsAction.AppSettings, state: DetailsState,
action: DetailsAction.AppSettings,
state: DetailsState,
): DetailsState {
return when (action) {
is DetailsAction.AppSettings.SwitchPrivacySetting -> {
@ -157,7 +161,8 @@ private fun handlePrivacyAction(
}
private fun prepareAllowedSecurityOptions(
card: Card?, currentSecurityOption: SecurityOption?,
card: CardDTO?,
currentSecurityOption: SecurityOption?,
): EnumSet<SecurityOption> {
val allowedSecurityOptions = EnumSet.of(SecurityOption.LongTap)
@ -173,7 +178,7 @@ private fun prepareAllowedSecurityOptions(
return allowedSecurityOptions
}
private fun Card.toCardInfo(): CardInfo {
private fun CardDTO.toCardInfo(): CardInfo {
val cardId = this.cardId.chunked(4).joinToString(separator = " ")
val issuer = this.issuer.name
val signedHashes = this.signedHashesCount()

View file

@ -2,7 +2,7 @@ package com.tangem.tap.features.details.redux
import android.net.Uri
import com.tangem.blockchain.common.Wallet
import com.tangem.common.card.Card
import com.tangem.domain.common.CardDTO
import com.tangem.domain.common.ScanResponse
import com.tangem.tap.common.entities.Button
import com.tangem.tap.common.entities.FiatCurrency
@ -20,13 +20,13 @@ data class DetailsState(
val privacyPolicyUrl: String? = null,
val createBackupAllowed: Boolean = false,
val appCurrency: FiatCurrency = FiatCurrency.Default,
val saveWallets: Boolean = true,
val saveAccessCodes: Boolean = true,
val saveWallets: Boolean = false,
val saveAccessCodes: Boolean = false,
) : StateType {
// if you do not delegate - the application crashes on startup,
// because twinCardsState has not been created yet
val twinCardsState: TwinCardsState by ReadOnlyProperty<Any, TwinCardsState> { thisRef, property ->
val twinCardsState: TwinCardsState by ReadOnlyProperty<Any, TwinCardsState> { _, _ ->
store.state.twinCardsState
}
@ -42,7 +42,7 @@ data class CardInfo(
data class CardSettingsState(
val cardInfo: CardInfo,
val card: Card,
val card: CardDTO,
val manageSecurityState: ManageSecurityState?,
val resetCardAllowed: Boolean,
val resetConfirmed: Boolean = false,

View file

@ -3,8 +3,8 @@ package com.tangem.tap.features.details.redux.walletconnect
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.DerivationStyle
import com.tangem.blockchain.common.WalletManager
import com.tangem.common.card.Card
import com.tangem.common.extensions.guard
import com.tangem.domain.common.CardDTO
import com.tangem.domain.common.ScanResponse
import com.tangem.domain.common.TapWorkarounds.derivationStyle
import com.tangem.domain.common.extensions.withMainContext
@ -240,7 +240,7 @@ class WalletConnectMiddleware {
handleScanResponse(scanResponse = scanResponse, session = session, blockchain = blockchain)
}
private fun getAvailableBlockchains(card: Card, walletState: WalletState): List<Blockchain> {
private fun getAvailableBlockchains(card: CardDTO, walletState: WalletState): List<Blockchain> {
return walletState.currencies.filter {
it.isBlockchain() && !it.isCustomCurrency(card.derivationStyle) && it.blockchain.isEvm()
}.map { it.blockchain }

View file

@ -1,8 +1,8 @@
package com.tangem.tap.features.disclaimer.redux
import android.net.Uri
import com.tangem.common.card.Card
import com.tangem.common.extensions.VoidCallback
import com.tangem.domain.common.CardDTO
import com.tangem.domain.common.ScanResponse
import com.tangem.domain.common.TapWorkarounds.isSaltPay
import org.rekotlin.StateType
@ -22,7 +22,7 @@ sealed class DisclaimerType(
companion object {
fun get(scanResponse: ScanResponse): DisclaimerType = get(scanResponse.card)
fun get(card: Card): DisclaimerType = when {
fun get(card: CardDTO): DisclaimerType = when {
card.isSaltPay -> SaltPay
else -> Tangem
}

View file

@ -14,4 +14,4 @@ sealed class HomeAction : Action {
data class GoToShop(val userCountryCode: String?) : HomeAction()
data class ChangeScanCardButtonState(val state: IndeterminateProgressButton) : HomeAction()
}
}

View file

@ -1,8 +1,8 @@
package com.tangem.tap.features.home.redux
import com.tangem.common.card.Card
import com.tangem.common.core.TangemError
import com.tangem.common.services.Result
import com.tangem.domain.common.CardDTO
import com.tangem.domain.common.ScanResponse
import com.tangem.domain.common.extensions.withIOContext
import com.tangem.domain.common.extensions.withMainContext
@ -45,7 +45,6 @@ import com.tangem.wallet.R
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.rekotlin.Action
import org.rekotlin.DispatchFunction
import org.rekotlin.Middleware
class HomeMiddleware {
@ -56,22 +55,23 @@ class HomeMiddleware {
}
}
private val homeMiddleware: Middleware<AppState> = { dispatch, state ->
private val homeMiddleware: Middleware<AppState> = { _, _ ->
{ next ->
{ action ->
handleHomeAction(state, action, dispatch)
handleHomeAction(action)
next(action)
}
}
}
private fun handleHomeAction(appState: () -> AppState?, action: Action, dispatch: DispatchFunction) {
private fun handleHomeAction(action: Action) {
when (action) {
is HomeAction.Init -> {
store.dispatch(GlobalAction.RestoreAppCurrency)
store.dispatch(GlobalAction.ExchangeManager.Init)
store.dispatch(GlobalAction.FetchUserCountry)
}
is HomeAction.ShouldScanCardOnResume -> {
if (action.shouldScanCard) {
store.dispatch(HomeAction.ShouldScanCardOnResume(false))
@ -123,7 +123,7 @@ private fun checkForUnfinishedBackupForSaltPay(
return
}
fun isTheSamePrimaryCard(card: Card): Boolean {
fun isTheSamePrimaryCard(card: CardDTO): Boolean {
return backupService.primaryCardId?.let { it == card.cardId } ?: false
}

View file

@ -3,7 +3,6 @@ package com.tangem.tap.features.onboarding
import com.tangem.domain.common.ProductType
import com.tangem.domain.common.ScanResponse
import com.tangem.tap.common.redux.navigation.AppScreen
import com.tangem.tap.domain.extensions.hasWallets
import com.tangem.tap.preferencesStorage
/**
@ -23,7 +22,7 @@ class OnboardingHelper {
cardInfoStorage.isActivationInProgress(cardId)
}
}
response.card.hasWallets() -> cardInfoStorage.isActivationInProgress(cardId)
response.card.wallets.isNotEmpty() -> cardInfoStorage.isActivationInProgress(cardId)
else -> true
}
}

View file

@ -22,7 +22,6 @@ 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.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
@ -79,7 +78,7 @@ private fun handleNoteAction(appState: () -> AppState?, action: Action, dispatch
}
is OnboardingNoteAction.DetermineStepOfScreen -> {
val step = when {
!card.hasWallets() -> OnboardingNoteStep.CreateWallet
card.wallets.isEmpty() -> OnboardingNoteStep.CreateWallet
noteState.walletBalance.balanceIsToppedUp() -> OnboardingNoteStep.Done
else -> OnboardingNoteStep.TopUpWallet
}

View file

@ -12,7 +12,6 @@ import com.tangem.tap.common.redux.AppState
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.hasWallets
import com.tangem.tap.domain.tokens.models.BlockchainNetwork
import com.tangem.tap.features.wallet.redux.WalletAction
import com.tangem.tap.scope
@ -21,7 +20,6 @@ import com.tangem.tap.tangemSdkManager
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.rekotlin.Action
import org.rekotlin.DispatchFunction
import org.rekotlin.Middleware
class OnboardingOtherCardsMiddleware {
@ -30,16 +28,16 @@ class OnboardingOtherCardsMiddleware {
}
}
private val onboardingOtherCardsMiddleware: Middleware<AppState> = { dispatch, state ->
private val onboardingOtherCardsMiddleware: Middleware<AppState> = { dispatch, _ ->
{ next ->
{ action ->
handleOtherCardsAction(action, dispatch)
handleOtherCardsAction(action)
next(action)
}
}
}
private fun handleOtherCardsAction(action: Action, dispatch: DispatchFunction) {
private fun handleOtherCardsAction(action: Action) {
if (action !is OnboardingOtherCardsAction) return
val globalState = store.state.globalState
val onboardingManager = globalState.onboardingState.onboardingManager ?: return
@ -60,7 +58,7 @@ private fun handleOtherCardsAction(action: Action, dispatch: DispatchFunction) {
}
is OnboardingOtherCardsAction.DetermineStepOfScreen -> {
val step = when {
!card.hasWallets() -> OnboardingOtherCardsStep.CreateWallet
card.wallets.isEmpty() -> OnboardingOtherCardsStep.CreateWallet
else -> OnboardingOtherCardsStep.Done
}
store.dispatch((OnboardingOtherCardsAction.SetStepOfScreen(step)))
@ -87,21 +85,32 @@ private fun handleOtherCardsAction(action: Action, dispatch: DispatchFunction) {
val updatedResponse = onboardingManager.scanResponse.copy(
card = result.data.card,
)
val updatedCard = updatedResponse.card
onboardingManager.scanResponse = updatedResponse
onboardingManager.activationStarted(updatedResponse.card.cardId)
onboardingManager.activationStarted(updatedCard.cardId)
val primaryBlockchain = updatedResponse.getBlockchain()
val blockchainNetworks = if (primaryBlockchain != Blockchain.Unknown) {
val primaryToken = updatedResponse.getPrimaryToken()
val blockchainNetwork =
BlockchainNetwork(primaryBlockchain, updatedResponse.card).updateTokens(
listOfNotNull(primaryToken),
BlockchainNetwork(
blockchain = primaryBlockchain,
card = updatedCard,
)
.updateTokens(
listOfNotNull(primaryToken),
)
listOf(blockchainNetwork)
} else {
listOf(
BlockchainNetwork(Blockchain.Bitcoin, updatedResponse.card),
BlockchainNetwork(Blockchain.Ethereum, updatedResponse.card),
BlockchainNetwork(
blockchain = Blockchain.Bitcoin,
card = updatedCard,
),
BlockchainNetwork(
blockchain = Blockchain.Ethereum,
card = updatedCard,
),
)
}
@ -126,5 +135,9 @@ private fun handleOtherCardsAction(action: Action, dispatch: DispatchFunction) {
withMainContext { store.dispatch(NavigationAction.NavigateTo(AppScreen.Wallet)) }
}
}
is OnboardingOtherCardsAction.Confetti.Hide,
is OnboardingOtherCardsAction.SetArtworkUrl,
is OnboardingOtherCardsAction.Confetti.Show,
-> Unit
}
}

View file

@ -150,6 +150,13 @@ private fun handle(action: Action, dispatch: DispatchFunction) {
finishCardActivation()
postUi(500) { store.dispatch(TwinCardsAction.Confetti.Show) }
}
TwinCardsStep.None,
TwinCardsStep.Warning,
TwinCardsStep.CreateFirstWallet,
TwinCardsStep.CreateSecondWallet,
TwinCardsStep.CreateThirdWallet,
-> Unit
}
}
is TwinCardsAction.Wallet.LaunchFirstStep -> {
@ -299,4 +306,4 @@ private fun handle(action: Action, dispatch: DispatchFunction) {
}
}
}
}
}

View file

@ -2,8 +2,8 @@ package com.tangem.tap.features.onboarding.products.wallet.redux
import com.tangem.blockchain.common.Blockchain
import com.tangem.common.CompletionResult
import com.tangem.common.card.Card
import com.tangem.common.extensions.ifNotNull
import com.tangem.domain.common.CardDTO
import com.tangem.domain.common.ScanResponse
import com.tangem.domain.common.TapWorkarounds.isSaltPay
import com.tangem.domain.common.extensions.withMainContext
@ -18,7 +18,6 @@ import com.tangem.tap.common.redux.AppState
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.hasWallets
import com.tangem.tap.domain.tokens.models.BlockchainNetwork
import com.tangem.tap.features.demo.DemoHelper
import com.tangem.tap.features.home.redux.HomeAction
@ -76,19 +75,23 @@ private fun handleWalletAction(action: Action, state: () -> AppState?, dispatch:
// it's possible when found unfinished backup for standard Wallet cards
store.dispatch(OnboardingWalletAction.ResumeBackup)
}
card.hasWallets() && card.backupStatus == Card.BackupStatus.NoBackup -> {
card.wallets.isNotEmpty() && card.backupStatus == CardDTO.BackupStatus.NoBackup -> {
store.dispatch(OnboardingWalletAction.ResumeBackup)
}
card.hasWallets() && card.backupStatus?.isActive == true -> {
card.wallets.isNotEmpty() && card.backupStatus?.isActive == true -> {
when {
// check for unfinished backup for saltPay cards. See more
scanResponse.isSaltPay() && backupService.hasIncompletedBackup -> {
store.dispatch(OnboardingWalletAction.ResumeBackup)
}
scanResponse.isSaltPay() -> {
store.dispatch(OnboardingWalletAction.GetToSaltPayStep)
store.dispatch(BackupAction.FinishBackup)
}
else -> store.dispatch(BackupAction.FinishBackup)
}
}
@ -125,8 +128,14 @@ private fun handleWalletAction(action: Action, state: () -> AppState?, dispatch:
)
onboardingManager.scanResponse = updatedResponse
val blockchainNetworks = listOf(
BlockchainNetwork(Blockchain.Bitcoin, result.data.card),
BlockchainNetwork(Blockchain.Ethereum, result.data.card),
BlockchainNetwork(
blockchain = Blockchain.Bitcoin,
card = result.data.card,
),
BlockchainNetwork(
blockchain = Blockchain.Ethereum,
card = result.data.card,
),
)
store.dispatch(
WalletAction.MultiWallet.SaveCurrencies(
@ -193,7 +202,7 @@ private fun updateScanResponseAfterBackup(
val card = if (backupState.backupCardsNumber > 0) {
val cardsCount = backupState.backupCardsNumber
scanResponse.card.copy(
backupStatus = Card.BackupStatus.Active(cardCount = cardsCount),
backupStatus = CardDTO.BackupStatus.Active(cardCount = cardsCount),
isAccessCodeSet = true,
)
} else {
@ -366,9 +375,10 @@ private fun startCardActivation(scanResponse: ScanResponse) {
* Standard Wallet cards finish activation at BackupAction.FinishBackup
* SaltPay cards finish activation at OnboardingWalletAction.FinishOnboarding
*/
internal fun finishCardActivation(backupState: BackupState, card: Card?) {
internal fun finishCardActivation(backupState: BackupState, card: CardDTO?) {
(listOf(backupState.primaryCardId, card?.cardId) + backupState.backupCardIds)
.distinct().filterNotNull()
.distinct()
.filterNotNull()
.forEach { cardId ->
preferencesStorage.usedCardsPrefStorage.activationFinished(cardId)
}

View file

@ -11,6 +11,7 @@ import com.tangem.common.extensions.guard
import com.tangem.common.extensions.isZero
import com.tangem.common.services.Result
import com.tangem.domain.common.extensions.successOr
import com.tangem.domain.common.util.UserWalletId
import com.tangem.network.api.paymentology.AttestationResponse
import com.tangem.network.api.paymentology.PaymentologyApiService
import com.tangem.network.api.paymentology.RegisterKYCRequest
@ -20,7 +21,6 @@ import com.tangem.network.api.paymentology.RegistrationResponse
import com.tangem.network.api.paymentology.tryExtractError
import com.tangem.operations.attestation.AttestWalletKeyResponse
import com.tangem.tap.common.extensions.safeUpdate
import com.tangem.tap.domain.extensions.UserWalletId
import com.tangem.tap.domain.getFirstToken
import com.tangem.tap.features.onboarding.products.wallet.saltPay.message.SaltPayActivationError
import java.math.BigDecimal
@ -123,7 +123,7 @@ class SaltPayActivationManager(
}
suspend fun claim(amountToClaim: BigDecimal, signer: TransactionSigner): Result<Unit> {
val result = gnosisRegistrator.transferFrom(amountToClaim, signer).successOr {
gnosisRegistrator.transferFrom(amountToClaim, signer).successOr {
return Result.Failure(SaltPayActivationError.ClaimTransactionFailed)
}
return Result.Success(Unit)
@ -192,4 +192,4 @@ class KYCUrlProvider(
.appendQueryParameter(kycProvider.externalIdParameterKey, kycRefId)
.build().toString()
}
}
}

View file

@ -11,9 +11,9 @@ import com.tangem.blockchain.common.TransactionError
import com.tangem.blockchain.common.TransactionSender
import com.tangem.blockchain.common.WalletManager
import com.tangem.blockchain.extensions.SimpleResult
import com.tangem.common.card.Card
import com.tangem.common.core.TangemSdkError
import com.tangem.common.services.Result
import com.tangem.domain.common.CardDTO
import com.tangem.domain.common.TapWorkarounds.isStart2Coin
import com.tangem.domain.common.extensions.withMainContext
import com.tangem.tap.DELAY_SDK_DIALOG_CLOSE
@ -150,7 +150,7 @@ private fun sendTransaction(
feeAmount: Amount,
destinationAddress: String,
transactionExtras: TransactionExtrasState,
card: Card,
card: CardDTO,
externalTransactionData: ExternalTransactionData?,
dispatch: (Action) -> Unit,
) {

View file

@ -1,8 +1,6 @@
package com.tangem.tap.features.wallet.models
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.DerivationStyle
import com.tangem.blockchain.common.Token
import com.tangem.domain.common.extensions.fromNetworkId
import com.tangem.domain.common.extensions.toCoinId
import com.tangem.domain.common.extensions.toNetworkId
@ -11,6 +9,8 @@ import com.tangem.network.api.tangemTech.TokenResponse
import com.tangem.tap.common.redux.global.CryptoCurrencyName
import com.tangem.tap.domain.tokens.models.BlockchainNetwork
import com.tangem.tap.features.tokens.redux.TokenWithBlockchain
import com.tangem.blockchain.common.Blockchain as SdkBlockchain
import com.tangem.blockchain.common.Token as SdkToken
sealed interface Currency {
val coinId: String?
@ -18,7 +18,7 @@ sealed interface Currency {
is Blockchain -> blockchain.toCoinId()
is Token -> token.id
}
val blockchain: com.tangem.blockchain.common.Blockchain
val blockchain: SdkBlockchain
val currencySymbol: CryptoCurrencyName
val derivationPath: String?
val currencyName: String
@ -33,15 +33,15 @@ sealed interface Currency {
}
data class Token(
val token: com.tangem.blockchain.common.Token,
override val blockchain: com.tangem.blockchain.common.Blockchain,
val token: SdkToken,
override val blockchain: SdkBlockchain,
override val derivationPath: String?,
) : Currency {
override val currencySymbol = token.symbol
}
data class Blockchain(
override val blockchain: com.tangem.blockchain.common.Blockchain,
override val blockchain: SdkBlockchain,
override val derivationPath: String?,
) : Currency {
override val currencySymbol: CryptoCurrencyName = blockchain.currency
@ -72,7 +72,7 @@ sealed interface Currency {
companion object {
fun fromBlockchainNetwork(
blockchainNetwork: BlockchainNetwork,
token: com.tangem.blockchain.common.Token? = null,
token: SdkToken? = null,
): Currency {
return if (token != null) {
Token(
@ -115,7 +115,7 @@ sealed interface Currency {
?: return null
return when {
tokenResponse.contractAddress != null -> Token(
com.tangem.blockchain.common.Token(
token = SdkToken(
name = tokenResponse.name,
symbol = tokenResponse.symbol,
contractAddress = tokenResponse.contractAddress!!,
@ -148,8 +148,8 @@ fun List<Currency>.toBlockchainNetworks(): List<BlockchainNetwork> {
return this.filter { it.isBlockchain() }.map { BlockchainNetwork(it.blockchain, it.derivationPath, getTokens(it)) }
}
private fun List<Currency>.getTokens(currency: Currency): List<Token> {
fun List<Currency>.getTokens(currency: Currency): List<SdkToken> {
return this
.filter { it.isToken() && it.blockchain == currency.blockchain && it.derivationPath == currency.derivationPath }
.mapNotNull { if (it is Currency.Token) it.token else null }
}
}

View file

@ -7,9 +7,8 @@ import com.tangem.blockchain.common.Token
import com.tangem.blockchain.common.Wallet
import com.tangem.blockchain.common.WalletManager
import com.tangem.blockchain.common.address.AddressType
import com.tangem.common.card.Card
import com.tangem.domain.common.CardDTO
import com.tangem.tap.common.entities.FiatCurrency
import com.tangem.tap.common.redux.ErrorAction
import com.tangem.tap.common.redux.NotificationAction
import com.tangem.tap.domain.TapError
import com.tangem.tap.domain.configurable.warningMessage.WarningMessage
@ -70,7 +69,7 @@ sealed class WalletAction : Action {
data class AddToken(val token: Token, val blockchain: BlockchainNetwork, val save: Boolean) : MultiWallet()
data class SaveCurrencies(
val blockchainNetworks: List<BlockchainNetwork>, val card: Card? = null,
val blockchainNetworks: List<BlockchainNetwork>, val card: CardDTO? = null,
) : MultiWallet()
data class TokenLoaded(
@ -123,9 +122,9 @@ sealed class WalletAction : Action {
object Failure : WalletAction()
}
class LoadCardInfo(val card: Card) : WalletAction()
class LoadCardInfo(val card: CardDTO) : WalletAction()
data class LoadArtwork(val card: Card, val artworkId: String?) : WalletAction() {
data class LoadArtwork(val card: CardDTO, val artworkId: String?) : WalletAction() {
data class Success(val artwork: Artwork) : WalletAction()
object Failure : WalletAction()
}
@ -134,10 +133,6 @@ sealed class WalletAction : Action {
data class Send(val amount: Amount? = null) : WalletAction()
object EmptyField : WalletAction(), ErrorAction {
override val error = TapError.PayIdEmptyField
}
data class CopyAddress(val address: String, val context: Context) : WalletAction() {
object Success : WalletAction(), NotificationAction {
override val messageResource = R.string.wallet_notification_address_copied
@ -186,7 +181,7 @@ sealed class WalletAction : Action {
data class SetWalletRent(
val wallet: Wallet,
val minRent: String,
val rentExempt: String
val rentExempt: String,
) : WalletAction()
data class RemoveWalletRent(val wallet: Wallet) : WalletAction()

View file

@ -4,8 +4,8 @@ import com.tangem.blockchain.common.BlockchainSdkError
import com.tangem.blockchain.common.SignatureCountValidator
import com.tangem.blockchain.common.Wallet
import com.tangem.blockchain.extensions.SimpleResult
import com.tangem.common.card.Card
import com.tangem.common.card.FirmwareVersion
import com.tangem.domain.common.CardDTO
import com.tangem.domain.common.ScanResponse
import com.tangem.domain.common.TapWorkarounds.isTestCard
import com.tangem.tap.common.extensions.dispatchOnMain
@ -13,10 +13,8 @@ import com.tangem.tap.common.extensions.isGreaterThan
import com.tangem.tap.common.redux.global.GlobalState
import com.tangem.tap.domain.configurable.warningMessage.WarningMessage
import com.tangem.tap.domain.configurable.warningMessage.WarningMessagesManager
import com.tangem.tap.domain.extensions.getSingleWallet
import com.tangem.tap.domain.extensions.hasSignedHashes
import com.tangem.tap.domain.extensions.isMultiwalletAllowed
import com.tangem.tap.domain.extensions.remainingSignatures
import com.tangem.tap.features.demo.isDemoCard
import com.tangem.tap.features.wallet.redux.WalletAction
import com.tangem.tap.network.NetworkConnectivity
@ -108,8 +106,8 @@ class WarningsMiddleware {
}
}
private fun showWarningLowRemainingSignaturesIfNeeded(card: Card) {
val remainingSignatures = card.remainingSignatures
private fun showWarningLowRemainingSignaturesIfNeeded(card: CardDTO) {
val remainingSignatures = card.wallets.firstOrNull()?.remainingSignatures
if (remainingSignatures != null &&
remainingSignatures <= WarningMessagesManager.REMAINING_SIGNATURES_WARNING
) {
@ -159,7 +157,7 @@ class WarningsMiddleware {
val validator = store.state.walletState.walletManagers.firstOrNull()
as? SignatureCountValidator
scope.launch {
val signedHashes = card.getSingleWallet()?.totalSignedHashes ?: 0
val signedHashes = card.wallets.firstOrNull()?.totalSignedHashes ?: 0
val result = validator?.validateSignatureCount(signedHashes)
withContext(Dispatchers.Main) {
when (result) {

View file

@ -3,7 +3,7 @@ package com.tangem.tap.features.wallet.ui.wallet
import android.widget.Button
import androidx.core.view.isVisible
import androidx.recyclerview.widget.LinearLayoutManager
import com.tangem.common.card.Card
import com.tangem.domain.common.CardDTO
import com.tangem.domain.common.TapWorkarounds.derivationStyle
import com.tangem.domain.common.TapWorkarounds.isTestCard
import com.tangem.tap.common.analytics.Analytics
@ -54,8 +54,8 @@ class MultiWalletView : WalletView() {
private fun setupWalletCardNumber(binding: FragmentWalletBinding) = with(binding) {
val card = store.state.globalState.scanResponse?.card
if (card?.backupStatus is Card.BackupStatus.Active) {
val cardCount = (card.backupStatus as Card.BackupStatus.Active).cardCount + 1
if (card?.backupStatus is CardDTO.BackupStatus.Active) {
val cardCount = (card.backupStatus as CardDTO.BackupStatus.Active).cardCount + 1
tvTwinCardNumber.show()
tvTwinCardNumber.text = tvTwinCardNumber.getQuantityString(R.plurals.card_label_card_count, cardCount)
} else {