Updated on 2026-08-14
This commit is contained in:
parent
4375e7687f
commit
0d993b5141
53 changed files with 430 additions and 356 deletions
|
|
@ -74,7 +74,7 @@ object TangemSdk {
|
|||
is TangemSdkError.UnsupportedWalletConfig -> TangemSdkError.UnsupportedWalletConfig()
|
||||
is TangemSdkError.CryptoUtilsError -> TangemSdkError.CryptoUtilsError(error.customMessage)
|
||||
is TangemSdkError.NetworkError -> TangemSdkError.NetworkError(error.customMessage)
|
||||
is TangemSdkError.ExceptionError -> TangemSdkError.ExceptionError(error.throwable)
|
||||
is TangemSdkError.ExceptionError -> TangemSdkError.ExceptionError(error.cause)
|
||||
is TangemSdkError.TooMuchBackupCards -> TangemSdkError.TooMuchBackupCards()
|
||||
is TangemSdkError.BackupCardRequired -> TangemSdkError.BackupCardRequired()
|
||||
is TangemSdkError.CertificateSignatureRequired -> TangemSdkError.CertificateSignatureRequired()
|
||||
|
|
@ -107,6 +107,8 @@ object TangemSdk {
|
|||
is TangemSdkError.BackupFailedFirmware -> TangemSdkError.BackupFailedFirmware()
|
||||
is TangemSdkError.UserForgotTheCode -> TangemSdkError.UserForgotTheCode()
|
||||
is TangemSdkError.BackupFailedIncompatibleBatch -> TangemSdkError.BackupFailedIncompatibleBatch()
|
||||
is TangemSdkError.BiometricsUnavailable -> error
|
||||
is TangemSdkError.BiometricsAuthenticationFailed -> error
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,10 +3,10 @@ package com.tangem.tap.common.analytics.converters
|
|||
import com.tangem.common.Converter
|
||||
import com.tangem.common.extensions.isZero
|
||||
import com.tangem.domain.common.ScanResponse
|
||||
import com.tangem.domain.common.util.userWalletId
|
||||
import com.tangem.tap.common.analytics.events.AnalyticsParam
|
||||
import com.tangem.tap.common.analytics.events.Basic
|
||||
import com.tangem.tap.common.analytics.filters.BasicTopUpFilter
|
||||
import com.tangem.tap.domain.extensions.getUserWalletId
|
||||
import com.tangem.tap.domain.extensions.isMultiwalletAllowed
|
||||
import com.tangem.tap.features.wallet.redux.ProgressState
|
||||
import com.tangem.tap.features.wallet.redux.WalletData
|
||||
|
|
@ -29,7 +29,7 @@ class BasicSignInEventConverter(
|
|||
currency = cardCurrency,
|
||||
batch = scanResponse.card.batchId,
|
||||
).apply {
|
||||
filterData = scanResponse.card.getUserWalletId()
|
||||
filterData = scanResponse.card.userWalletId.stringValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -43,7 +43,7 @@ class BasicTopUpEventConverter(
|
|||
val cardCurrency = ParamCardCurrencyConverter().convert(scanResponse) ?: return null
|
||||
|
||||
val data = BasicTopUpFilter.Data(
|
||||
walletId = scanResponse.card.getUserWalletId(),
|
||||
walletId = scanResponse.card.userWalletId.stringValue,
|
||||
cardBalanceState = AnalyticsParam.CardBalanceState.from(value.walletsData),
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import com.tangem.blockchain.common.Token
|
|||
import com.tangem.blockchain.common.Wallet
|
||||
import com.tangem.blockchain.common.WalletManager
|
||||
import com.tangem.blockchain.common.address.Address
|
||||
import com.tangem.common.card.CardWallet
|
||||
import com.tangem.domain.common.CardDTO
|
||||
import com.tangem.domain.common.ScanResponse
|
||||
import com.tangem.tap.common.extensions.stripZeroPlainString
|
||||
import com.tangem.tap.domain.extensions.getUserWalletId
|
||||
|
|
@ -92,7 +92,7 @@ class AdditionalFeedbackInfo {
|
|||
)
|
||||
}
|
||||
|
||||
private fun formatSignedHashes(wallets: List<CardWallet>): String {
|
||||
private fun formatSignedHashes(wallets: List<CardDTO.Wallet>): String {
|
||||
return wallets.joinToString("\n") { "Signed hashes: ${it.curve.curve} - ${it.totalSignedHashes}" }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.tangem.tap.common.redux.global
|
|||
|
||||
import com.tangem.domain.redux.domainStore
|
||||
import com.tangem.domain.redux.global.DomainGlobalAction
|
||||
import com.tangem.tap.common.extensions.replaceBy
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
import com.tangem.tap.features.onboarding.OnboardingManager
|
||||
import com.tangem.tap.preferencesStorage
|
||||
|
|
@ -49,12 +50,19 @@ fun globalReducer(action: Action, state: AppState, appStateHolder: AppStateHolde
|
|||
is GlobalAction.SetWarningManager -> globalState.copy(warningManager = action.warningManager)
|
||||
is GlobalAction.UpdateWalletSignedHashes -> {
|
||||
val card = globalState.scanResponse?.card ?: return globalState
|
||||
val wallet = card.wallet(action.walletPublicKey) ?: return globalState
|
||||
val newCardInstance = card.updateWallet(
|
||||
wallet.copy(
|
||||
totalSignedHashes = action.walletSignedHashes,
|
||||
remainingSignatures = action.remainingSignatures,
|
||||
),
|
||||
val wallet = card.wallets
|
||||
.firstOrNull { it.publicKey.contentEquals(action.walletPublicKey) }
|
||||
?: return globalState
|
||||
|
||||
val newCardInstance = card.copy(
|
||||
wallets = card.wallets.toMutableList().also { walletsMutable ->
|
||||
walletsMutable.replaceBy(
|
||||
item = wallet.copy(
|
||||
totalSignedHashes = action.walletSignedHashes,
|
||||
remainingSignatures = action.remainingSignatures,
|
||||
),
|
||||
) { it.index == wallet.index }
|
||||
},
|
||||
)
|
||||
globalState.copy(scanResponse = globalState.scanResponse.copy(card = newCardInstance))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
package com.tangem.tap.domain
|
||||
|
||||
import CreateProductWalletTask
|
||||
import CreateProductWalletTaskResponse
|
||||
import android.content.Context
|
||||
import androidx.annotation.StringRes
|
||||
import com.tangem.Message
|
||||
|
|
@ -10,7 +8,6 @@ import com.tangem.blockchain.common.Blockchain
|
|||
import com.tangem.common.CardFilter
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.common.SuccessResponse
|
||||
import com.tangem.common.card.Card
|
||||
import com.tangem.common.card.FirmwareVersion
|
||||
import com.tangem.common.core.CardIdDisplayFormat
|
||||
import com.tangem.common.core.CardSessionRunnable
|
||||
|
|
@ -18,6 +15,8 @@ import com.tangem.common.core.Config
|
|||
import com.tangem.common.core.TangemSdkError
|
||||
import com.tangem.common.extensions.ByteArrayKey
|
||||
import com.tangem.common.hdWallet.DerivationPath
|
||||
import com.tangem.common.map
|
||||
import com.tangem.domain.common.CardDTO
|
||||
import com.tangem.domain.common.ScanResponse
|
||||
import com.tangem.operations.CommandResponse
|
||||
import com.tangem.operations.ScanTask
|
||||
|
|
@ -29,6 +28,8 @@ import com.tangem.operations.pins.SetUserCodeCommand
|
|||
import com.tangem.tap.common.analytics.Analytics
|
||||
import com.tangem.tap.common.analytics.events.Basic
|
||||
import com.tangem.tap.domain.tasks.CreateWalletAndRescanTask
|
||||
import com.tangem.tap.domain.tasks.product.CreateProductWalletTask
|
||||
import com.tangem.tap.domain.tasks.product.CreateProductWalletTaskResponse
|
||||
import com.tangem.tap.domain.tasks.product.ResetToFactorySettingsTask
|
||||
import com.tangem.tap.domain.tasks.product.ScanProductTask
|
||||
import com.tangem.tap.domain.tokens.UserTokensRepository
|
||||
|
|
@ -73,12 +74,13 @@ class TangemSdkManager(private val tangemSdk: TangemSdk, private val context: Co
|
|||
}
|
||||
}
|
||||
|
||||
suspend fun createWallet(cardId: String?): CompletionResult<Card> {
|
||||
suspend fun createWallet(cardId: String?): CompletionResult<CardDTO> {
|
||||
return runTaskAsyncReturnOnMain(
|
||||
CreateWalletAndRescanTask(),
|
||||
cardId,
|
||||
initialMessage = Message(context.getString(R.string.initial_message_create_wallet_body)),
|
||||
)
|
||||
.map { CardDTO(it) }
|
||||
}
|
||||
|
||||
suspend fun derivePublicKeys(
|
||||
|
|
@ -88,12 +90,13 @@ class TangemSdkManager(private val tangemSdk: TangemSdk, private val context: Co
|
|||
return runTaskAsyncReturnOnMain(DeriveMultipleWalletPublicKeysTask(derivations), cardId)
|
||||
}
|
||||
|
||||
suspend fun resetToFactorySettings(card: Card): CompletionResult<Card> {
|
||||
suspend fun resetToFactorySettings(cardId: String): CompletionResult<CardDTO> {
|
||||
return runTaskAsyncReturnOnMain(
|
||||
ResetToFactorySettingsTask(),
|
||||
card.cardId,
|
||||
runnable = ResetToFactorySettingsTask(),
|
||||
cardId = cardId,
|
||||
initialMessage = Message(context.getString(R.string.card_settings_reset_card_to_factory)),
|
||||
)
|
||||
.map { CardDTO(it) }
|
||||
}
|
||||
|
||||
suspend fun setPasscode(cardId: String?): CompletionResult<SuccessResponse> {
|
||||
|
|
@ -128,11 +131,12 @@ class TangemSdkManager(private val tangemSdk: TangemSdk, private val context: Co
|
|||
)
|
||||
}
|
||||
|
||||
suspend fun scanCard(): CompletionResult<Card> {
|
||||
suspend fun scanCard(): CompletionResult<CardDTO> {
|
||||
return runTaskAsyncReturnOnMain(
|
||||
ScanTask(),
|
||||
runnable = ScanTask(),
|
||||
initialMessage = Message(context.getString(R.string.initial_message_tap_header)),
|
||||
)
|
||||
.map { CardDTO(it) }
|
||||
}
|
||||
|
||||
suspend fun <T : CommandResponse> runTaskAsync(
|
||||
|
|
@ -150,7 +154,9 @@ class TangemSdkManager(private val tangemSdk: TangemSdk, private val context: Co
|
|||
}
|
||||
|
||||
private suspend fun <T : CommandResponse> runTaskAsyncReturnOnMain(
|
||||
runnable: CardSessionRunnable<T>, cardId: String? = null, initialMessage: Message? = null,
|
||||
runnable: CardSessionRunnable<T>,
|
||||
cardId: String? = null,
|
||||
initialMessage: Message? = null,
|
||||
): CompletionResult<T> {
|
||||
val result = runTaskAsync(runnable, cardId, initialMessage)
|
||||
return withContext(Dispatchers.Main) { result }
|
||||
|
|
|
|||
|
|
@ -5,13 +5,13 @@ import com.tangem.TangemSdk
|
|||
import com.tangem.blockchain.common.TransactionSigner
|
||||
import com.tangem.blockchain.common.Wallet
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.common.card.Card
|
||||
import com.tangem.domain.common.CardDTO
|
||||
import com.tangem.tap.domain.tasks.SignHashesTask
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
|
||||
class TangemSigner(
|
||||
private val card: Card,
|
||||
private val card: CardDTO,
|
||||
private val tangemSdk: TangemSdk,
|
||||
private val initialMessage: Message,
|
||||
private val accessCode: String? = null,
|
||||
|
|
|
|||
|
|
@ -64,8 +64,7 @@ sealed class TapError(
|
|||
) : TapError(-1), MultiMessageError
|
||||
}
|
||||
|
||||
sealed class TapSdkError(override val messageResId: Int?) : Throwable(), TangemError {
|
||||
final override val code: Int = 50100
|
||||
sealed class TapSdkError(override val messageResId: Int?) : TangemError(code = 50100) {
|
||||
override var customMessage: String = code.toString()
|
||||
|
||||
object CardForDifferentApp : TapSdkError(R.string.alert_unsupported_card)
|
||||
|
|
@ -88,4 +87,4 @@ fun TangemTechError.toTapError(): TapError {
|
|||
}
|
||||
}
|
||||
|
||||
class NoDataError(message: String) : TapError.CustomError(customMessage = message)
|
||||
class NoDataError(message: String) : TapError.CustomError(customMessage = message)
|
||||
|
|
@ -6,8 +6,8 @@ import com.tangem.blockchain.common.Token
|
|||
import com.tangem.blockchain.common.Wallet
|
||||
import com.tangem.blockchain.common.WalletManager
|
||||
import com.tangem.blockchain.common.WalletManagerFactory
|
||||
import com.tangem.common.card.Card
|
||||
import com.tangem.common.services.Result
|
||||
import com.tangem.domain.common.CardDTO
|
||||
import com.tangem.domain.common.ScanResponse
|
||||
import com.tangem.domain.common.TapWorkarounds.isStart2Coin
|
||||
import com.tangem.domain.common.TapWorkarounds.isTestCard
|
||||
|
|
@ -96,7 +96,7 @@ class TapWalletManager {
|
|||
store.dispatch(
|
||||
WalletAction.MultiWallet.ShowWalletBackupWarning(
|
||||
show = data.card.settings.isBackupAllowed
|
||||
&& data.card.backupStatus == Card.BackupStatus.NoBackup,
|
||||
&& data.card.backupStatus == CardDTO.BackupStatus.NoBackup,
|
||||
),
|
||||
)
|
||||
loadData(data)
|
||||
|
|
|
|||
|
|
@ -1,58 +1,45 @@
|
|||
package com.tangem.tap.domain.extensions
|
||||
|
||||
import com.tangem.common.card.Card
|
||||
import com.tangem.common.card.CardWallet
|
||||
import com.tangem.common.card.EllipticCurve
|
||||
import com.tangem.common.card.FirmwareVersion
|
||||
import com.tangem.common.extensions.calculateSha256
|
||||
import com.tangem.common.extensions.toHexString
|
||||
import com.tangem.common.services.Result
|
||||
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
|
||||
import com.tangem.domain.common.TwinCardNumber
|
||||
import com.tangem.domain.common.extensions.calculateHmacSha256
|
||||
import com.tangem.domain.common.getTwinCardNumber
|
||||
import com.tangem.domain.common.isTangemTwin
|
||||
import com.tangem.operations.attestation.CardVerifyAndGetInfo
|
||||
import com.tangem.operations.attestation.OnlineCardVerifier
|
||||
import com.tangem.tap.features.wallet.redux.Artwork
|
||||
|
||||
val Card.remainingSignatures: Int?
|
||||
get() = this.getSingleWallet()?.remainingSignatures
|
||||
val CardDTO.remainingSignatures: Int?
|
||||
get() = this.wallets.firstOrNull()?.remainingSignatures
|
||||
|
||||
val Card.isWalletDataSupported: Boolean
|
||||
val CardDTO.isWalletDataSupported: Boolean
|
||||
get() = this.firmwareVersion.major >= 4
|
||||
|
||||
val Card.isMultiwalletAllowed: Boolean
|
||||
val CardDTO.isMultiwalletAllowed: Boolean
|
||||
get() {
|
||||
return !isTangemTwin() && !isStart2Coin && !isTangemNote && !isSaltPay
|
||||
&& (firmwareVersion >= FirmwareVersion.MultiWalletAvailable ||
|
||||
getSingleWallet()?.curve == EllipticCurve.Secp256k1)
|
||||
return !isTangemTwin() && !isStart2Coin && !isTangemNote && !isSaltPay &&
|
||||
(firmwareVersion >= FirmwareVersion.MultiWalletAvailable ||
|
||||
wallets.firstOrNull()?.curve == EllipticCurve.Secp256k1)
|
||||
}
|
||||
|
||||
val Card.isHdWalletAllowedByApp: Boolean
|
||||
val CardDTO.isHdWalletAllowedByApp: Boolean
|
||||
get() = settings.isHDWalletAllowed && !isSaltPay
|
||||
|
||||
fun Card.getSingleWallet(): CardWallet? {
|
||||
return wallets.firstOrNull()
|
||||
fun CardDTO.hasSignedHashes(): Boolean {
|
||||
return wallets.any { (it.totalSignedHashes ?: 0) > 0 }
|
||||
}
|
||||
|
||||
fun Card.hasWallets(): Boolean = wallets.isNotEmpty()
|
||||
|
||||
fun Card.hasNoWallets(): Boolean = wallets.isEmpty()
|
||||
|
||||
fun Card.hasSingleWallet(): Boolean = wallets.size == 1
|
||||
|
||||
fun Card.hasSignedHashes(): Boolean {
|
||||
return wallets.any { it.totalSignedHashes ?: 0 > 0 }
|
||||
fun CardDTO.signedHashesCount(): Int {
|
||||
return wallets.sumOf { it.totalSignedHashes ?: 0 }
|
||||
}
|
||||
|
||||
fun Card.signedHashesCount(): Int {
|
||||
return wallets.map { it.totalSignedHashes ?: 0 }.sum()
|
||||
}
|
||||
|
||||
suspend fun Card.getOrLoadCardArtworkUrl(cardInfo: Result<CardVerifyAndGetInfo.Response.Item>? = null): String {
|
||||
suspend fun CardDTO.getOrLoadCardArtworkUrl(cardInfo: Result<CardVerifyAndGetInfo.Response.Item>? = null): String {
|
||||
fun ifAnyError(): String {
|
||||
return when {
|
||||
cardId.startsWith(Artwork.SERGIO_CARD_ID) -> Artwork.SERGIO_CARD_URL
|
||||
|
|
@ -67,42 +54,28 @@ suspend fun Card.getOrLoadCardArtworkUrl(cardInfo: Result<CardVerifyAndGetInfo.R
|
|||
}
|
||||
}
|
||||
|
||||
val cardInfoResult = cardInfo ?: OnlineCardVerifier().getCardInfo(cardId, cardPublicKey)
|
||||
return when (cardInfoResult) {
|
||||
return when (val cardInfoResult = cardInfo ?: OnlineCardVerifier().getCardInfo(cardId, cardPublicKey)) {
|
||||
is Result.Success -> {
|
||||
val artworkId = cardInfoResult.data.artwork?.id
|
||||
if (artworkId == null || artworkId.isEmpty()) {
|
||||
if (artworkId.isNullOrEmpty()) {
|
||||
ifAnyError()
|
||||
} else {
|
||||
OnlineCardVerifier.getUrlForArtwork(cardId, cardPublicKey.toHexString(), artworkId)
|
||||
}
|
||||
}
|
||||
|
||||
is Result.Failure -> ifAnyError()
|
||||
}
|
||||
}
|
||||
|
||||
fun Card.getArtworkUrl(artworkId: String?): String? {
|
||||
fun CardDTO.getArtworkUrl(artworkId: String?): String? {
|
||||
return when {
|
||||
artworkId != null -> {
|
||||
OnlineCardVerifier.getUrlForArtwork(cardId, cardPublicKey.toHexString(), artworkId)
|
||||
}
|
||||
|
||||
cardId.startsWith(Artwork.SERGIO_CARD_ID) -> Artwork.SERGIO_CARD_URL
|
||||
cardId.startsWith(Artwork.MARTA_CARD_ID) -> Artwork.MARTA_CARD_URL
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
fun Card.getUserWalletId(): String {
|
||||
val walletPublicKey = this.wallets.firstOrNull()?.publicKey ?: return ""
|
||||
return UserWalletId(walletPublicKey).stringValue
|
||||
}
|
||||
|
||||
class UserWalletId(val walletPublicKey: ByteArray) {
|
||||
val stringValue: String = calculateUserId(walletPublicKey)
|
||||
|
||||
private fun calculateUserId(walletPublicKey: ByteArray): String {
|
||||
val message = "UserWalletID".toByteArray()
|
||||
val keyHash = walletPublicKey.calculateSha256()
|
||||
return message.calculateHmacSha256(keyHash).toHexString()
|
||||
}
|
||||
}
|
||||
|
|
@ -7,13 +7,12 @@ import com.tangem.blockchain.common.DerivationStyle
|
|||
import com.tangem.blockchain.common.Wallet
|
||||
import com.tangem.blockchain.common.WalletManager
|
||||
import com.tangem.blockchain.common.WalletManagerFactory
|
||||
import com.tangem.common.card.Card
|
||||
import com.tangem.common.card.CardWallet
|
||||
import com.tangem.common.card.EllipticCurve
|
||||
import com.tangem.common.extensions.guard
|
||||
import com.tangem.common.extensions.hexToBytes
|
||||
import com.tangem.common.extensions.toMapKey
|
||||
import com.tangem.common.hdWallet.DerivationPath
|
||||
import com.tangem.domain.common.CardDTO
|
||||
import com.tangem.domain.common.SaltPayWorkaround
|
||||
import com.tangem.domain.common.ScanResponse
|
||||
import com.tangem.domain.common.TapWorkarounds.isTestCard
|
||||
|
|
@ -82,7 +81,7 @@ fun WalletManagerFactory.makeWalletManagerForApp(
|
|||
)
|
||||
}
|
||||
|
||||
private fun getDerivationParams(derivationPath: String?, card: Card): DerivationParams? {
|
||||
private fun getDerivationParams(derivationPath: String?, card: CardDTO): DerivationParams? {
|
||||
return derivationPath?.let {
|
||||
DerivationParams.Custom(
|
||||
DerivationPath(it),
|
||||
|
|
@ -132,7 +131,7 @@ fun WalletManagerFactory.makePrimaryWalletManager(
|
|||
)
|
||||
}
|
||||
|
||||
private fun selectWallet(wallets: List<CardWallet>): CardWallet? {
|
||||
private fun selectWallet(wallets: List<CardDTO.Wallet>): CardDTO.Wallet? {
|
||||
return when (wallets.size) {
|
||||
0 -> null
|
||||
1 -> wallets[0]
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
package com.tangem.tap.domain.tasks.product
|
||||
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.common.card.Card
|
||||
|
|
@ -9,6 +11,8 @@ import com.tangem.common.extensions.ByteArrayKey
|
|||
import com.tangem.common.extensions.guard
|
||||
import com.tangem.common.extensions.toMapKey
|
||||
import com.tangem.common.hdWallet.DerivationPath
|
||||
import com.tangem.common.map
|
||||
import com.tangem.domain.common.CardDTO
|
||||
import com.tangem.domain.common.KeyWalletPublicKey
|
||||
import com.tangem.domain.common.ProductType
|
||||
import com.tangem.domain.common.TapWorkarounds.derivationStyle
|
||||
|
|
@ -19,19 +23,37 @@ import com.tangem.operations.backup.PrimaryCard
|
|||
import com.tangem.operations.backup.StartPrimaryCardLinkingTask
|
||||
import com.tangem.operations.derivation.DeriveMultipleWalletPublicKeysTask
|
||||
import com.tangem.operations.derivation.ExtendedPublicKeysMap
|
||||
import com.tangem.operations.wallet.CreateWalletResponse
|
||||
import com.tangem.operations.wallet.CreateWalletTask
|
||||
import com.tangem.tap.domain.tasks.product.CreateWalletsTask
|
||||
import com.tangem.tap.domain.tasks.product.ProductCommandProcessor
|
||||
import com.tangem.tap.domain.tasks.product.getCurvesForNonCreatedWallets
|
||||
import com.tangem.tap.features.demo.DemoHelper
|
||||
|
||||
import com.tangem.operations.wallet.CreateWalletResponse as SdkCreateWalletResponse
|
||||
|
||||
data class CreateProductWalletTaskResponse(
|
||||
val card: Card,
|
||||
val card: CardDTO,
|
||||
val derivedKeys: Map<KeyWalletPublicKey, ExtendedPublicKeysMap> = mapOf(),
|
||||
val primaryCard: PrimaryCard? = null
|
||||
) : CommandResponse
|
||||
val primaryCard: PrimaryCard? = null,
|
||||
) : CommandResponse {
|
||||
constructor(
|
||||
card: Card,
|
||||
derivedKeys: Map<KeyWalletPublicKey, ExtendedPublicKeysMap> = mapOf(),
|
||||
primaryCard: PrimaryCard? = null,
|
||||
) : this(
|
||||
card = CardDTO(card),
|
||||
derivedKeys = derivedKeys,
|
||||
primaryCard = primaryCard,
|
||||
)
|
||||
}
|
||||
|
||||
private data class CreateWalletResponse(
|
||||
val cardId: String,
|
||||
val wallet: CardDTO.Wallet,
|
||||
) {
|
||||
constructor(
|
||||
sdkResponse: SdkCreateWalletResponse,
|
||||
) : this(
|
||||
cardId = sdkResponse.cardId,
|
||||
wallet = CardDTO.Wallet(sdkResponse.wallet),
|
||||
)
|
||||
}
|
||||
|
||||
class CreateProductWalletTask(
|
||||
private val type: ProductType,
|
||||
|
|
@ -39,29 +61,32 @@ class CreateProductWalletTask(
|
|||
|
||||
override fun run(
|
||||
session: CardSession,
|
||||
callback: (result: CompletionResult<CreateProductWalletTaskResponse>) -> Unit
|
||||
callback: (result: CompletionResult<CreateProductWalletTaskResponse>) -> Unit,
|
||||
) {
|
||||
val card = session.environment.card.guard {
|
||||
callback(CompletionResult.Failure(TangemSdkError.CardError()))
|
||||
return
|
||||
}
|
||||
val cardDto = CardDTO(card)
|
||||
|
||||
val commandProcessor = when (type) {
|
||||
ProductType.Note -> CreateWalletTangemNote()
|
||||
ProductType.Twins -> throw UnsupportedOperationException("Use the TwinCardsManager to create a wallet")
|
||||
else -> CreateWalletTangemWallet()
|
||||
}
|
||||
commandProcessor.proceed(card, session) {
|
||||
commandProcessor.proceed(cardDto, session) {
|
||||
when (it) {
|
||||
is CompletionResult.Success -> {
|
||||
val result = when (commandProcessor) {
|
||||
is CreateWalletTangemWallet -> {
|
||||
it.data as CreateProductWalletTaskResponse
|
||||
}
|
||||
|
||||
else -> CreateProductWalletTaskResponse(card = session.environment.card!!)
|
||||
}
|
||||
callback(CompletionResult.Success(result))
|
||||
}
|
||||
|
||||
is CompletionResult.Failure -> callback(CompletionResult.Failure(it.error))
|
||||
}
|
||||
}
|
||||
|
|
@ -70,7 +95,7 @@ class CreateProductWalletTask(
|
|||
|
||||
private class CreateWalletTangemNote : ProductCommandProcessor<CreateWalletResponse> {
|
||||
override fun proceed(
|
||||
card: Card,
|
||||
card: CardDTO,
|
||||
session: CardSession,
|
||||
callback: (result: CompletionResult<CreateWalletResponse>) -> Unit,
|
||||
) {
|
||||
|
|
@ -94,52 +119,65 @@ private class CreateWalletTangemNote : ProductCommandProcessor<CreateWalletRespo
|
|||
} else {
|
||||
intersectCurves[0]
|
||||
}
|
||||
CreateWalletTask(curve).run(session, callback)
|
||||
CreateWalletTask(curve).run(session) { result ->
|
||||
callback(result.map { CreateWalletResponse(it) })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class CreateWalletTangemWallet : ProductCommandProcessor<CreateProductWalletTaskResponse> {
|
||||
|
||||
private lateinit var card: Card
|
||||
private var primaryCard: PrimaryCard? = null
|
||||
|
||||
override fun proceed(
|
||||
card: Card,
|
||||
card: CardDTO,
|
||||
session: CardSession,
|
||||
callback: (result: CompletionResult<CreateProductWalletTaskResponse>) -> Unit,
|
||||
) {
|
||||
this.card = card
|
||||
val curves = card.getCurvesForNonCreatedWallets()
|
||||
|
||||
if (curves.isEmpty()) {
|
||||
val createWalletResponses = card.wallets.map { CreateWalletResponse(card.cardId, it) }
|
||||
proceedWithCreatedWallets(createWalletResponses, session, callback)
|
||||
val createWalletResponses = card.wallets.map { wallet ->
|
||||
CreateWalletResponse(card.cardId, wallet)
|
||||
}
|
||||
proceedWithCreatedWallets(card, createWalletResponses, session, callback)
|
||||
return
|
||||
}
|
||||
|
||||
CreateWalletsTask(curves).run(session) { result ->
|
||||
when (result) {
|
||||
is CompletionResult.Success -> {
|
||||
proceedWithCreatedWallets(result.data.createWalletResponses, session, callback)
|
||||
proceedWithCreatedWallets(
|
||||
card = card,
|
||||
createWalletResponses = result.data.createWalletResponses.map { CreateWalletResponse(it) },
|
||||
session = session,
|
||||
callback = callback,
|
||||
)
|
||||
}
|
||||
|
||||
is CompletionResult.Failure -> {
|
||||
callback(CompletionResult.Failure(result.error))
|
||||
}
|
||||
is CompletionResult.Failure -> callback(CompletionResult.Failure(result.error))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun proceedWithCreatedWallets(
|
||||
card: CardDTO,
|
||||
createWalletResponses: List<CreateWalletResponse>,
|
||||
session: CardSession,
|
||||
callback: (result: CompletionResult<CreateProductWalletTaskResponse>) -> Unit,
|
||||
) {
|
||||
when {
|
||||
card.settings.isBackupAllowed -> {
|
||||
linkPrimaryCard(createWalletResponses, session, callback)
|
||||
linkPrimaryCard(card, createWalletResponses, session, callback)
|
||||
}
|
||||
|
||||
card.settings.isHDWalletAllowed -> {
|
||||
deriveKeys(createWalletResponses, session, callback)
|
||||
deriveKeys(card, createWalletResponses, session, callback)
|
||||
}
|
||||
|
||||
else -> {
|
||||
callback(
|
||||
CompletionResult.Success(
|
||||
|
|
@ -151,6 +189,7 @@ private class CreateWalletTangemWallet : ProductCommandProcessor<CreateProductWa
|
|||
}
|
||||
|
||||
private fun linkPrimaryCard(
|
||||
card: CardDTO,
|
||||
createWalletResponse: List<CreateWalletResponse>,
|
||||
session: CardSession,
|
||||
callback: (result: CompletionResult<CreateProductWalletTaskResponse>) -> Unit,
|
||||
|
|
@ -161,8 +200,9 @@ private class CreateWalletTangemWallet : ProductCommandProcessor<CreateProductWa
|
|||
primaryCard = result.data
|
||||
when {
|
||||
card.settings.isHDWalletAllowed -> {
|
||||
deriveKeys(createWalletResponse, session, callback)
|
||||
deriveKeys(card, createWalletResponse, session, callback)
|
||||
}
|
||||
|
||||
else -> {
|
||||
callback(
|
||||
CompletionResult.Success(
|
||||
|
|
@ -174,6 +214,7 @@ private class CreateWalletTangemWallet : ProductCommandProcessor<CreateProductWa
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
is CompletionResult.Failure -> {
|
||||
callback(CompletionResult.Failure(result.error))
|
||||
}
|
||||
|
|
@ -182,13 +223,14 @@ private class CreateWalletTangemWallet : ProductCommandProcessor<CreateProductWa
|
|||
}
|
||||
|
||||
private fun deriveKeys(
|
||||
card: CardDTO,
|
||||
createWalletResponse: List<CreateWalletResponse>,
|
||||
session: CardSession,
|
||||
callback: (result: CompletionResult<CreateProductWalletTaskResponse>) -> Unit,
|
||||
) {
|
||||
val map = mutableMapOf<ByteArrayKey, List<DerivationPath>>()
|
||||
createWalletResponse.forEach { response ->
|
||||
val blockchainsForCurve = getBlockchains(response.cardId).filter {
|
||||
val blockchainsForCurve = getBlockchains(response.cardId, card).filter {
|
||||
it.getSupportedCurves().contains(response.wallet.curve)
|
||||
}
|
||||
val derivationPaths = blockchainsForCurve.mapNotNull { it.derivationPath(card.derivationStyle) }
|
||||
|
|
@ -210,17 +252,21 @@ private class CreateWalletTangemWallet : ProductCommandProcessor<CreateProductWa
|
|||
CreateProductWalletTaskResponse(
|
||||
card = session.environment.card!!,
|
||||
derivedKeys = result.data.entries,
|
||||
primaryCard = primaryCard
|
||||
)
|
||||
)
|
||||
primaryCard = primaryCard,
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
is CompletionResult.Failure -> callback(CompletionResult.Failure(result.error))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getBlockchains(cardId: String): List<Blockchain> {
|
||||
private fun getBlockchains(
|
||||
cardId: String,
|
||||
card: CardDTO,
|
||||
): List<Blockchain> {
|
||||
return when {
|
||||
DemoHelper.isDemoCardId(cardId) -> DemoHelper.config.demoBlockchains
|
||||
card.isTestCard -> listOf(Blockchain.BitcoinTestnet, Blockchain.EthereumTestnet)
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
package com.tangem.tap.domain.tasks.product
|
||||
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.common.card.Card
|
||||
import com.tangem.common.core.CardSession
|
||||
import com.tangem.domain.common.CardDTO
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
interface ProductCommandProcessor<T> {
|
||||
fun proceed(
|
||||
card: Card,
|
||||
card: CardDTO,
|
||||
session: CardSession,
|
||||
callback: (result: CompletionResult<T>) -> Unit,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import com.tangem.common.extensions.guard
|
|||
import com.tangem.common.extensions.toHexString
|
||||
import com.tangem.common.extensions.toMapKey
|
||||
import com.tangem.common.hdWallet.DerivationPath
|
||||
import com.tangem.domain.common.CardDTO
|
||||
import com.tangem.domain.common.ProductType
|
||||
import com.tangem.domain.common.ScanResponse
|
||||
import com.tangem.domain.common.TapWorkarounds.isExcluded
|
||||
|
|
@ -31,7 +32,6 @@ import com.tangem.operations.derivation.DeriveMultipleWalletPublicKeysTask
|
|||
import com.tangem.operations.issuerAndUserData.ReadIssuerDataCommand
|
||||
import com.tangem.tap.domain.TapSdkError
|
||||
import com.tangem.tap.domain.extensions.getPrimaryCurve
|
||||
import com.tangem.tap.domain.extensions.getSingleWallet
|
||||
import com.tangem.tap.domain.extensions.isMultiwalletAllowed
|
||||
import com.tangem.tap.domain.tokens.UserTokensRepository
|
||||
import com.tangem.tap.domain.tokens.models.BlockchainNetwork
|
||||
|
|
@ -53,19 +53,20 @@ class ScanProductTask(
|
|||
callback(CompletionResult.Failure(TangemSdkError.MissingPreflightRead()))
|
||||
return
|
||||
}
|
||||
val cardDto = CardDTO(card)
|
||||
|
||||
val error = getErrorIfExcludedCard(card)
|
||||
val error = getErrorIfExcludedCard(cardDto)
|
||||
if (error != null) {
|
||||
callback(CompletionResult.Failure(error))
|
||||
return
|
||||
}
|
||||
|
||||
val commandProcessor = when {
|
||||
card.isTangemNote -> ScanNoteProcessor()
|
||||
card.isTangemTwins -> ScanTwinProcessor()
|
||||
cardDto.isTangemNote -> ScanNoteProcessor()
|
||||
cardDto.isTangemTwins -> ScanTwinProcessor()
|
||||
else -> ScanWalletProcessor(userTokensRepository, additionalBlockchainsToDerive)
|
||||
}
|
||||
commandProcessor.proceed(card, session) { processorResult ->
|
||||
commandProcessor.proceed(cardDto, session) { processorResult ->
|
||||
when (processorResult) {
|
||||
is CompletionResult.Success -> ScanTask().run(session) { scanTaskResult ->
|
||||
when (scanTaskResult) {
|
||||
|
|
@ -73,7 +74,7 @@ class ScanProductTask(
|
|||
// it need because processorResult.data.card doesn't contains attestation result
|
||||
// and CardWallet.derivedKeys
|
||||
val processorScanResponseWithNewCard = processorResult.data.copy(
|
||||
card = scanTaskResult.data,
|
||||
card = CardDTO(scanTaskResult.data),
|
||||
)
|
||||
callback(CompletionResult.Success(processorScanResponseWithNewCard))
|
||||
}
|
||||
|
|
@ -85,7 +86,7 @@ class ScanProductTask(
|
|||
}
|
||||
}
|
||||
|
||||
private fun getErrorIfExcludedCard(card: Card): TangemError? {
|
||||
private fun getErrorIfExcludedCard(card: CardDTO): TangemError? {
|
||||
if (card.isExcluded) return TapSdkError.CardForDifferentApp
|
||||
if (card.isNotSupportedInThatRelease) return TapSdkError.CardNotSupportedByRelease
|
||||
return null
|
||||
|
|
@ -94,7 +95,7 @@ class ScanProductTask(
|
|||
|
||||
private class ScanNoteProcessor : ProductCommandProcessor<ScanResponse> {
|
||||
override fun proceed(
|
||||
card: Card,
|
||||
card: CardDTO,
|
||||
session: CardSession,
|
||||
callback: (result: CompletionResult<ScanResponse>) -> Unit,
|
||||
) {
|
||||
|
|
@ -117,7 +118,7 @@ private class ScanWalletProcessor(
|
|||
|
||||
var primaryCard: PrimaryCard? = null
|
||||
override fun proceed(
|
||||
card: Card,
|
||||
card: CardDTO,
|
||||
session: CardSession,
|
||||
callback: (result: CompletionResult<ScanResponse>) -> Unit,
|
||||
) {
|
||||
|
|
@ -125,7 +126,7 @@ private class ScanWalletProcessor(
|
|||
}
|
||||
|
||||
private fun createMissingWalletsIfNeeded(
|
||||
card: Card,
|
||||
card: CardDTO,
|
||||
session: CardSession,
|
||||
callback: (result: CompletionResult<ScanResponse>) -> Unit,
|
||||
) {
|
||||
|
|
@ -159,13 +160,13 @@ private class ScanWalletProcessor(
|
|||
}
|
||||
|
||||
private fun startLinkingForBackupIfNeeded(
|
||||
card: Card,
|
||||
card: CardDTO,
|
||||
session: CardSession,
|
||||
callback: (result: CompletionResult<ScanResponse>) -> Unit,
|
||||
) {
|
||||
val activationInProgress = preferencesStorage.usedCardsPrefStorage.isActivationInProgress(card.cardId)
|
||||
|
||||
if ((card.backupStatus == Card.BackupStatus.NoBackup && card.wallets.isNotEmpty())
|
||||
if ((card.backupStatus == CardDTO.BackupStatus.NoBackup && card.wallets.isNotEmpty())
|
||||
&& (activationInProgress || card.isSaltPay)
|
||||
) {
|
||||
StartPrimaryCardLinkingTask().run(session) { linkingResult ->
|
||||
|
|
@ -185,7 +186,7 @@ private class ScanWalletProcessor(
|
|||
}
|
||||
|
||||
private fun deriveKeysIfNeeded(
|
||||
card: Card,
|
||||
card: CardDTO,
|
||||
session: CardSession,
|
||||
callback: (result: CompletionResult<ScanResponse>) -> Unit,
|
||||
) {
|
||||
|
|
@ -227,25 +228,46 @@ private class ScanWalletProcessor(
|
|||
}
|
||||
}
|
||||
|
||||
private suspend fun getBlockchainsToDerive(card: Card): List<BlockchainNetwork> {
|
||||
private suspend fun getBlockchainsToDerive(card: CardDTO): List<BlockchainNetwork> {
|
||||
val userTokensRepository = userTokensRepository ?: return emptyList()
|
||||
val blockchainsToDerive = userTokensRepository.loadBlockchainsToDerive(card).toMutableList().ifEmpty {
|
||||
mutableListOf(
|
||||
BlockchainNetwork(Blockchain.Bitcoin, card),
|
||||
BlockchainNetwork(Blockchain.Ethereum, card),
|
||||
)
|
||||
}
|
||||
val blockchainsToDerive = userTokensRepository.loadBlockchainsToDerive(card)
|
||||
.toMutableList()
|
||||
.ifEmpty {
|
||||
mutableListOf(
|
||||
BlockchainNetwork(
|
||||
blockchain = Blockchain.Bitcoin,
|
||||
card = card,
|
||||
),
|
||||
BlockchainNetwork(
|
||||
blockchain = Blockchain.Ethereum,
|
||||
card = card,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
if (card.settings.isHDWalletAllowed) {
|
||||
blockchainsToDerive.addAll(
|
||||
listOf(
|
||||
BlockchainNetwork(Blockchain.Ethereum, card),
|
||||
BlockchainNetwork(Blockchain.EthereumTestnet, card),
|
||||
BlockchainNetwork(
|
||||
blockchain = Blockchain.Ethereum,
|
||||
card = card,
|
||||
),
|
||||
BlockchainNetwork(
|
||||
blockchain = Blockchain.EthereumTestnet,
|
||||
card = card,
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
if (additionalBlockchainsToDerive != null) {
|
||||
blockchainsToDerive.addAll(additionalBlockchainsToDerive.map { BlockchainNetwork(it, card) })
|
||||
blockchainsToDerive.addAll(
|
||||
additionalBlockchainsToDerive.map {
|
||||
BlockchainNetwork(
|
||||
blockchain = it,
|
||||
card = card,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
if (!card.useOldStyleDerivation) {
|
||||
blockchainsToDerive.removeAll(
|
||||
|
|
@ -255,13 +277,18 @@ private class ScanWalletProcessor(
|
|||
Blockchain.RSK,
|
||||
Blockchain.Fantom, Blockchain.FantomTestnet,
|
||||
Blockchain.Avalanche, Blockchain.AvalancheTestnet,
|
||||
).map { BlockchainNetwork(it, card) },
|
||||
).map {
|
||||
BlockchainNetwork(
|
||||
blockchain = it,
|
||||
card = card,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
return blockchainsToDerive.distinct()
|
||||
}
|
||||
|
||||
private suspend fun collectDerivations(card: Card): Map<ByteArrayKey, List<DerivationPath>> {
|
||||
private suspend fun collectDerivations(card: CardDTO): Map<ByteArrayKey, List<DerivationPath>> {
|
||||
val blockchains = getBlockchainsToDerive(card)
|
||||
val derivations = mutableMapOf<ByteArrayKey, List<DerivationPath>>()
|
||||
|
||||
|
|
@ -287,14 +314,14 @@ private class ScanWalletProcessor(
|
|||
|
||||
private class ScanTwinProcessor : ProductCommandProcessor<ScanResponse> {
|
||||
override fun proceed(
|
||||
card: Card,
|
||||
card: CardDTO,
|
||||
session: CardSession,
|
||||
callback: (result: CompletionResult<ScanResponse>) -> Unit,
|
||||
) {
|
||||
ReadIssuerDataCommand().run(session) { readDataResult ->
|
||||
when (readDataResult) {
|
||||
is CompletionResult.Success -> {
|
||||
val publicKey = card.getSingleWallet()?.publicKey
|
||||
val publicKey = card.wallets.firstOrNull()?.publicKey
|
||||
if (publicKey == null) {
|
||||
val response = ScanResponse(
|
||||
card = card,
|
||||
|
|
@ -332,7 +359,7 @@ private class ScanTwinProcessor : ProductCommandProcessor<ScanResponse> {
|
|||
}
|
||||
}
|
||||
|
||||
fun Card.getCurvesForNonCreatedWallets(): List<EllipticCurve> {
|
||||
fun CardDTO.getCurvesForNonCreatedWallets(): List<EllipticCurve> {
|
||||
val curvesPresent = wallets.map { it.curve }.toSet()
|
||||
val curvesForNonCreatedWallets = supportedCurves.subtract(curvesPresent + EllipticCurve.Secp256r1)
|
||||
return curvesForNonCreatedWallets.toList()
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ package com.tangem.tap.domain.termsOfUse
|
|||
import android.content.res.Resources
|
||||
import android.net.Uri
|
||||
import androidx.core.os.ConfigurationCompat
|
||||
import com.tangem.common.card.Card
|
||||
import java.util.Locale
|
||||
import com.tangem.domain.common.CardDTO
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
|
|
@ -13,7 +13,7 @@ class CardTou {
|
|||
private val locale: Locale =
|
||||
ConfigurationCompat.getLocales(Resources.getSystem().configuration).get(0)!!
|
||||
|
||||
fun getUrl(card: Card): Uri? {
|
||||
fun getUrl(card: CardDTO): Uri? {
|
||||
val issuerName = card.issuer.name
|
||||
if (issuerName.lowercase(Locale.getDefault()) != "start2coin") return null
|
||||
|
||||
|
|
|
|||
|
|
@ -2,10 +2,11 @@ package com.tangem.tap.domain.tokens
|
|||
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.common.card.FirmwareVersion
|
||||
import com.tangem.domain.common.CardDTO
|
||||
|
||||
object CurrenciesRepository {
|
||||
fun getBlockchains(
|
||||
cardFirmware: FirmwareVersion,
|
||||
cardFirmware: CardDTO.FirmwareVersion,
|
||||
isTestNet: Boolean = false,
|
||||
): List<Blockchain> {
|
||||
val blockchains = if (cardFirmware < FirmwareVersion.MultiWalletAvailable) {
|
||||
|
|
@ -26,6 +27,4 @@ object CurrenciesRepository {
|
|||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -2,13 +2,13 @@ package com.tangem.tap.domain.tokens
|
|||
|
||||
import android.content.Context
|
||||
import com.tangem.blockchain.common.DerivationStyle
|
||||
import com.tangem.common.card.Card
|
||||
import com.tangem.common.services.Result
|
||||
import com.tangem.domain.common.CardDTO
|
||||
import com.tangem.domain.common.util.userWalletId
|
||||
import com.tangem.network.api.tangemTech.TangemTechService
|
||||
import com.tangem.network.api.tangemTech.UserTokensResponse
|
||||
import com.tangem.tap.common.AndroidFileReader
|
||||
import com.tangem.tap.domain.NoDataError
|
||||
import com.tangem.tap.domain.extensions.getUserWalletId
|
||||
import com.tangem.tap.domain.tokens.models.BlockchainNetwork
|
||||
import com.tangem.tap.features.demo.DemoHelper
|
||||
import com.tangem.tap.features.wallet.models.Currency
|
||||
|
|
@ -23,8 +23,8 @@ class UserTokensRepository(
|
|||
private val storageService: UserTokensStorageService,
|
||||
private val networkService: UserTokensNetworkService,
|
||||
) {
|
||||
suspend fun getUserTokens(card: Card): List<Currency> {
|
||||
val userId = card.getUserWalletId()
|
||||
suspend fun getUserTokens(card: CardDTO): List<Currency> {
|
||||
val userId = card.userWalletId.stringValue
|
||||
if (DemoHelper.isDemoCardId(card.cardId)) {
|
||||
return loadTokensOffline(card, userId).ifEmpty { loadDemoCurrencies() }
|
||||
}
|
||||
|
|
@ -36,25 +36,28 @@ class UserTokensRepository(
|
|||
return when (val networkResult = networkService.getUserTokens(userId)) {
|
||||
is Result.Success -> {
|
||||
val tokens = networkResult.data.tokens.mapNotNull { Currency.fromTokenResponse(it) }
|
||||
storageService.saveUserTokens(card.getUserWalletId(), tokens.toUserTokensResponse())
|
||||
storageService.saveUserTokens(userId, tokens.toUserTokensResponse())
|
||||
tokens.distinct()
|
||||
}
|
||||
|
||||
is Result.Failure -> {
|
||||
handleGetUserTokensFailure(card = card, userId = userId, error = networkResult.error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun saveUserTokens(card: Card, tokens: List<Currency>) {
|
||||
suspend fun saveUserTokens(card: CardDTO, tokens: List<Currency>) {
|
||||
val userId = card.userWalletId.stringValue
|
||||
val userTokens = tokens.toUserTokensResponse()
|
||||
networkService.saveUserTokens(card.getUserWalletId(), userTokens)
|
||||
storageService.saveUserTokens(card.getUserWalletId(), userTokens)
|
||||
networkService.saveUserTokens(userId, userTokens)
|
||||
storageService.saveUserTokens(userId, userTokens)
|
||||
}
|
||||
|
||||
suspend fun removeUserTokens(card: Card) {
|
||||
suspend fun removeUserTokens(card: CardDTO) {
|
||||
val userId = card.userWalletId.stringValue
|
||||
val userTokens = emptyList<Currency>().toUserTokensResponse()
|
||||
networkService.saveUserTokens(card.getUserWalletId(), userTokens)
|
||||
storageService.saveUserTokens(card.getUserWalletId(), userTokens)
|
||||
networkService.saveUserTokens(userId, userTokens)
|
||||
storageService.saveUserTokens(userId, userTokens)
|
||||
}
|
||||
|
||||
private fun List<Currency>.toUserTokensResponse(): UserTokensResponse {
|
||||
|
|
@ -66,8 +69,8 @@ class UserTokensRepository(
|
|||
)
|
||||
}
|
||||
|
||||
suspend fun loadBlockchainsToDerive(card: Card): List<BlockchainNetwork> {
|
||||
val userId = card.getUserWalletId()
|
||||
suspend fun loadBlockchainsToDerive(card: CardDTO): List<BlockchainNetwork> {
|
||||
val userId = card.userWalletId.stringValue
|
||||
val blockchainNetworks = loadTokensOffline(card, userId).toBlockchainNetworks()
|
||||
|
||||
if (DemoHelper.isDemoCardId(card.cardId)) {
|
||||
|
|
@ -89,7 +92,7 @@ class UserTokensRepository(
|
|||
}
|
||||
|
||||
private suspend fun handleGetUserTokensFailure(
|
||||
card: Card,
|
||||
card: CardDTO,
|
||||
userId: String,
|
||||
error: Throwable,
|
||||
): List<Currency> {
|
||||
|
|
@ -107,7 +110,7 @@ class UserTokensRepository(
|
|||
}
|
||||
}
|
||||
|
||||
private suspend fun loadTokensOffline(card: Card, userId: String): List<Currency> {
|
||||
private suspend fun loadTokensOffline(card: CardDTO, userId: String): List<Currency> {
|
||||
return storageService.getUserTokens(userId) ?: storageService.getUserTokens(card)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ package com.tangem.tap.domain.tokens
|
|||
|
||||
import com.squareup.moshi.JsonAdapter
|
||||
import com.tangem.Log
|
||||
import com.tangem.common.card.Card
|
||||
import com.tangem.domain.common.CardDTO
|
||||
import com.tangem.network.api.tangemTech.UserTokensResponse
|
||||
import com.tangem.network.common.MoshiConverter
|
||||
import com.tangem.tap.common.FileReader
|
||||
|
|
@ -28,7 +28,7 @@ class UserTokensStorageService(
|
|||
}
|
||||
|
||||
@Deprecated("")
|
||||
suspend fun getUserTokens(card: Card): List<Currency> {
|
||||
suspend fun getUserTokens(card: CardDTO): List<Currency> {
|
||||
val blockchainNetworks =
|
||||
oldUserTokensRepository.loadSavedCurrencies(card.cardId, card.settings.isHDWalletAllowed)
|
||||
return blockchainNetworks.flatMap { it.toCurrencies() }
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ import com.squareup.moshi.JsonClass
|
|||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.Token
|
||||
import com.tangem.blockchain.common.WalletManager
|
||||
import com.tangem.common.card.Card
|
||||
import com.tangem.common.extensions.calculateHashCode
|
||||
import com.tangem.domain.common.CardDTO
|
||||
import com.tangem.domain.common.TapWorkarounds.derivationStyle
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
|
|
@ -15,16 +15,18 @@ data class BlockchainNetwork(
|
|||
val tokens: List<Token>
|
||||
) {
|
||||
|
||||
constructor(blockchain: Blockchain, card: Card) : this(
|
||||
constructor(
|
||||
blockchain: Blockchain,
|
||||
card: CardDTO,
|
||||
) : this(
|
||||
blockchain = blockchain,
|
||||
derivationPath = if (card.settings.isHDWalletAllowed) blockchain.derivationPath(card.derivationStyle)?.rawPath else null,
|
||||
tokens = emptyList()
|
||||
tokens = emptyList(),
|
||||
)
|
||||
|
||||
|
||||
fun updateTokens(tokens: List<Token>): BlockchainNetwork {
|
||||
return copy(
|
||||
tokens = (this.tokens + tokens).distinct()
|
||||
tokens = (this.tokens + tokens).distinct(),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import com.tangem.domain.common.TwinsHelper
|
|||
import com.tangem.operations.wallet.CreateWalletResponse
|
||||
import com.tangem.operations.wallet.CreateWalletTask
|
||||
import com.tangem.operations.wallet.PurgeWalletCommand
|
||||
import com.tangem.tap.domain.extensions.getSingleWallet
|
||||
|
||||
class CreateFirstTwinWalletTask : CardSessionRunnable<CreateWalletResponse> {
|
||||
override fun run(
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ class CreateSecondTwinWalletTask(
|
|||
|
||||
override fun run(session: CardSession, callback: (result: CompletionResult<CreateWalletResponse>) -> Unit) {
|
||||
val card = session.environment.card
|
||||
val publicKey = card?.getSingleWallet()?.publicKey
|
||||
val publicKey = card?.wallets?.firstOrNull()?.publicKey
|
||||
if (publicKey != null) {
|
||||
if (TwinsHelper.getTwinCardNumber(card.cardId) == TwinCardNumber.First) {
|
||||
callback(CompletionResult.Failure(WrongTwinCard(TwinCardNumber.Second)))
|
||||
|
|
@ -63,4 +63,4 @@ class CreateSecondTwinWalletTask(
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,9 +6,9 @@ import com.tangem.Message
|
|||
import com.tangem.blockchain.extensions.Result
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.common.KeyPair
|
||||
import com.tangem.common.card.Card
|
||||
import com.tangem.common.extensions.hexToBytes
|
||||
import com.tangem.common.extensions.toHexString
|
||||
import com.tangem.domain.common.CardDTO
|
||||
import com.tangem.domain.common.ScanResponse
|
||||
import com.tangem.network.common.MoshiConverter
|
||||
import com.tangem.operations.wallet.CreateWalletResponse
|
||||
|
|
@ -16,7 +16,7 @@ import com.tangem.tap.common.AssetReader
|
|||
import com.tangem.tap.tangemSdkManager
|
||||
|
||||
class TwinCardsManager(
|
||||
card: Card,
|
||||
card: CardDTO,
|
||||
assetReader: AssetReader,
|
||||
) {
|
||||
|
||||
|
|
@ -91,7 +91,6 @@ class TwinCardsManager(
|
|||
}
|
||||
|
||||
private class Issuer(
|
||||
val id: String,
|
||||
val privateKey: String,
|
||||
val publicKey: String,
|
||||
)
|
||||
|
|
@ -13,7 +13,6 @@ import com.tangem.operations.issuerAndUserData.ReadIssuerDataCommand
|
|||
import com.tangem.operations.issuerAndUserData.ReadIssuerDataResponse
|
||||
import com.tangem.operations.issuerAndUserData.WriteIssuerDataCommand
|
||||
import com.tangem.operations.sign.SignHashCommand
|
||||
import com.tangem.tap.domain.extensions.getSingleWallet
|
||||
|
||||
class WriteProtectedIssuerDataTask(
|
||||
private val twinPublicKey: ByteArray, private val issuerKeys: KeyPair,
|
||||
|
|
@ -25,7 +24,7 @@ class WriteProtectedIssuerDataTask(
|
|||
) {
|
||||
SignHashCommand(
|
||||
twinPublicKey.calculateSha256(),
|
||||
session.environment.card!!.getSingleWallet()!!.publicKey
|
||||
session.environment.card!!.wallets.first().publicKey,
|
||||
)
|
||||
.run(session) { signResult ->
|
||||
when (signResult) {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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 {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,4 +14,4 @@ sealed class HomeAction : Action {
|
|||
data class GoToShop(val userCountryCode: String?) : HomeAction()
|
||||
|
||||
data class ChangeScanCardButtonState(val state: IndeterminateProgressButton) : HomeAction()
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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) {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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,
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
}
|
||||
}
|
||||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.tap.network.exchangeServices
|
||||
|
||||
import com.tangem.common.card.Card
|
||||
import com.tangem.domain.common.CardDTO
|
||||
import com.tangem.domain.common.TapWorkarounds.isStart2Coin
|
||||
import com.tangem.tap.features.demo.isDemoCard
|
||||
import com.tangem.tap.features.wallet.models.Currency
|
||||
|
|
@ -9,7 +9,7 @@ import com.tangem.tap.features.wallet.models.Currency
|
|||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
class CardExchangeRules(
|
||||
val cardProvider: () -> Card?,
|
||||
val cardProvider: () -> CardDTO?,
|
||||
) : ExchangeRules {
|
||||
|
||||
override fun featureIsSwitchedOn(): Boolean {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import com.tangem.blockchain.common.AmountType
|
|||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.Token
|
||||
import com.tangem.blockchain.extensions.Result
|
||||
import com.tangem.common.card.Card
|
||||
import com.tangem.domain.common.CardDTO
|
||||
import com.tangem.tap.common.extensions.safeUpdate
|
||||
import com.tangem.tap.common.redux.global.CryptoCurrencyName
|
||||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
|
|
@ -86,8 +86,9 @@ class CurrencyExchangeManager(
|
|||
}
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
suspend fun CurrencyExchangeManager.buyErc20TestnetTokens(
|
||||
card: Card,
|
||||
card: CardDTO,
|
||||
walletManager: EthereumWalletManager,
|
||||
token: Token,
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.tap.proxy
|
||||
|
||||
import com.tangem.common.card.Card
|
||||
import com.tangem.domain.common.CardDTO
|
||||
import com.tangem.domain.common.ScanResponse
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
import com.tangem.tap.domain.TangemSdkManager
|
||||
|
|
@ -20,7 +20,7 @@ class AppStateHolder {
|
|||
var mainStore: Store<AppState>? = null
|
||||
var tangemSdkManager: TangemSdkManager? = null
|
||||
|
||||
fun getActualCard(): Card? {
|
||||
fun getActualCard(): CardDTO? {
|
||||
return scanResponse?.card
|
||||
}
|
||||
}
|
||||
|
|
@ -4,15 +4,15 @@ import com.tangem.blockchain.common.Blockchain
|
|||
import com.tangem.blockchain.common.DerivationParams
|
||||
import com.tangem.blockchain.common.DerivationStyle
|
||||
import com.tangem.blockchain.common.WalletManagerFactory
|
||||
import com.tangem.common.card.Card
|
||||
import com.tangem.domain.common.CardDTO
|
||||
import com.tangem.domain.common.TapWorkarounds.derivationStyle
|
||||
import com.tangem.domain.common.extensions.fromNetworkId
|
||||
import com.tangem.domain.common.extensions.toNetworkId
|
||||
import com.tangem.domain.common.util.userWalletId
|
||||
import com.tangem.lib.crypto.UserWalletManager
|
||||
import com.tangem.lib.crypto.models.Currency
|
||||
import com.tangem.lib.crypto.models.NativeToken
|
||||
import com.tangem.lib.crypto.models.NonNativeToken
|
||||
import com.tangem.tap.domain.extensions.getUserWalletId
|
||||
import com.tangem.tap.domain.extensions.makeWalletManagerForApp
|
||||
import com.tangem.tap.domain.tokens.models.BlockchainNetwork
|
||||
import com.tangem.tap.features.wallet.redux.WalletAction
|
||||
|
|
@ -54,7 +54,7 @@ class UserWalletManagerImpl(
|
|||
}
|
||||
|
||||
override fun getWalletId(): String {
|
||||
return appStateHolder.getActualCard()?.getUserWalletId() ?: ""
|
||||
return appStateHolder.getActualCard()?.userWalletId?.stringValue ?: ""
|
||||
}
|
||||
|
||||
override suspend fun isTokenAdded(currency: Currency): Boolean {
|
||||
|
|
@ -100,7 +100,7 @@ class UserWalletManagerImpl(
|
|||
}
|
||||
}
|
||||
|
||||
private fun addNativeTokenToWalletAction(token: NativeToken, card: Card): Action {
|
||||
private fun addNativeTokenToWalletAction(token: NativeToken, card: CardDTO): Action {
|
||||
val blockchain = Blockchain.fromNetworkId(token.networkId)
|
||||
val scanResponse = appStateHolder.scanResponse
|
||||
if (blockchain != null && scanResponse != null) {
|
||||
|
|
|
|||
|
|
@ -58,11 +58,10 @@ object Versions {
|
|||
// endregion Other libraries
|
||||
|
||||
// region Tangem
|
||||
const val tangemBlockchainSdk = "develop-140"
|
||||
|
||||
// const val tangemBlockchainSdk = "0.0.1"
|
||||
const val tangemCardSgk = "develop-169"
|
||||
// const val tangemCardSgk = "0.0.1"
|
||||
const val tangemBlockchainSdk = "0.0.1"
|
||||
// const val tangemBlockchainSdk = "develop-140"
|
||||
const val tangemCardSgk = "0.0.1"
|
||||
// const val tangemCardSgk = "develop-165"
|
||||
// endregion Tangem
|
||||
|
||||
// region Testing
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package com.tangem.domain.common
|
|||
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.Token
|
||||
import com.tangem.common.card.Card
|
||||
import com.tangem.common.card.EllipticCurve
|
||||
import com.tangem.common.card.WalletData
|
||||
import com.tangem.common.extensions.ByteArrayKey
|
||||
|
|
@ -12,7 +11,6 @@ import com.tangem.domain.common.TapWorkarounds.getTangemNoteBlockchain
|
|||
import com.tangem.domain.common.TapWorkarounds.isSaltPay
|
||||
import com.tangem.domain.common.TapWorkarounds.isSaltPayVisa
|
||||
import com.tangem.domain.common.TapWorkarounds.isSaltPayWallet
|
||||
import com.tangem.domain.common.TapWorkarounds.isTangemNote
|
||||
import com.tangem.domain.common.TapWorkarounds.isTangemTwins
|
||||
import com.tangem.domain.common.TapWorkarounds.isTestCard
|
||||
import com.tangem.operations.CommandResponse
|
||||
|
|
@ -23,7 +21,7 @@ import com.tangem.operations.derivation.ExtendedPublicKeysMap
|
|||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
data class ScanResponse(
|
||||
val card: Card,
|
||||
val card: CardDTO,
|
||||
val productType: ProductType,
|
||||
val walletData: WalletData?,
|
||||
val secondTwinPublicKey: String? = null,
|
||||
|
|
@ -67,20 +65,22 @@ data class ScanResponse(
|
|||
return hasDerivation(blockchain, DerivationPath(rawDerivationPath))
|
||||
}
|
||||
|
||||
fun hasDerivation(blockchain: Blockchain, derivationPath: DerivationPath): Boolean {
|
||||
private fun hasDerivation(blockchain: Blockchain, derivationPath: DerivationPath): Boolean {
|
||||
val isTestnet = card.isTestCard || blockchain.isTestnet()
|
||||
return when {
|
||||
Blockchain.secp256k1Blockchains(isTestnet).contains(blockchain) -> {
|
||||
hasDerivation(EllipticCurve.Secp256k1, derivationPath)
|
||||
}
|
||||
|
||||
Blockchain.ed25519OnlyBlockchains(isTestnet).contains(blockchain) -> {
|
||||
hasDerivation(EllipticCurve.Ed25519, derivationPath)
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
fun hasDerivation(curve: EllipticCurve, derivationPath: DerivationPath): Boolean {
|
||||
private fun hasDerivation(curve: EllipticCurve, derivationPath: DerivationPath): Boolean {
|
||||
val foundWallet = card.wallets.firstOrNull { it.curve == curve }
|
||||
?: return false
|
||||
val extendedPublicKeysMap = derivedKeys[foundWallet.publicKey.toMapKey()] ?: return false
|
||||
|
|
@ -93,12 +93,4 @@ enum class ProductType {
|
|||
Note, Twins, Wallet, SaltPay
|
||||
}
|
||||
|
||||
val Card.productType: ProductType
|
||||
get() = when {
|
||||
isTangemTwins -> ProductType.Twins
|
||||
isTangemNote -> ProductType.Note
|
||||
isSaltPay -> ProductType.SaltPay
|
||||
else -> ProductType.Wallet
|
||||
}
|
||||
|
||||
typealias KeyWalletPublicKey = ByteArrayKey
|
||||
|
|
@ -17,18 +17,32 @@ object TapWorkarounds {
|
|||
return cardIssuer?.lowercase(Locale.US) == START_2_COIN_ISSUER
|
||||
}
|
||||
|
||||
val Card.isStart2Coin: Boolean
|
||||
val CardDTO.isTangemTwins: Boolean
|
||||
get() = TwinsHelper.getTwinCardNumber(cardId) != null
|
||||
|
||||
//TODO: replace by reading files from a card
|
||||
val CardDTO.isTangemNote: Boolean
|
||||
get() = tangemNoteBatches.contains(batchId)
|
||||
|
||||
val CardDTO.isStart2Coin: Boolean
|
||||
get() = isStart2CoinIssuer(issuer.name)
|
||||
|
||||
val Card.isTestCard: Boolean
|
||||
val CardDTO.isSaltPay: Boolean
|
||||
get() = isSaltPayVisa || isSaltPayWallet
|
||||
|
||||
val CardDTO.isSaltPayVisa: Boolean
|
||||
get() = SaltPayWorkaround.isVisaBatchId(batchId)
|
||||
|
||||
val CardDTO.isSaltPayWallet: Boolean
|
||||
get() = SaltPayWorkaround.isWalletCardId(cardId)
|
||||
|
||||
val CardDTO.isTestCard: Boolean
|
||||
get() = batchId == TEST_CARD_BATCH && cardId.startsWith(TEST_CARD_ID_STARTS_WITH)
|
||||
|
||||
val Card.useOldStyleDerivation: Boolean
|
||||
val CardDTO.useOldStyleDerivation: Boolean
|
||||
get() = batchId == "AC01" || batchId == "AC02" || batchId == "CB95"
|
||||
|
||||
val Card.derivationStyle: DerivationStyle?
|
||||
val CardDTO.derivationStyle: DerivationStyle?
|
||||
get() = if (!settings.isHDWalletAllowed) {
|
||||
Int.MAX_VALUE
|
||||
null
|
||||
} else if (useOldStyleDerivation) {
|
||||
DerivationStyle.LEGACY
|
||||
|
|
@ -36,15 +50,18 @@ object TapWorkarounds {
|
|||
DerivationStyle.NEW
|
||||
}
|
||||
|
||||
val Card.isNotSupportedInThatRelease: Boolean
|
||||
val CardDTO.isExcluded: Boolean
|
||||
get() {
|
||||
val excludedBatch = excludedBatches.contains(batchId)
|
||||
val excludedIssuerName = excludedIssuers.contains(issuer.name.uppercase(Locale.ROOT))
|
||||
return excludedBatch || excludedIssuerName
|
||||
}
|
||||
|
||||
val CardDTO.isNotSupportedInThatRelease: Boolean
|
||||
get() = false
|
||||
|
||||
val Card.isTangemTwins: Boolean
|
||||
get() = TwinsHelper.getTwinCardNumber(cardId) != null
|
||||
|
||||
//TODO: replace by reading files from a card
|
||||
val Card.isTangemNote: Boolean
|
||||
get() = tangemNoteBatches.contains(batchId)
|
||||
fun CardDTO.getTangemNoteBlockchain(): Blockchain? =
|
||||
tangemNoteBatches[batchId] ?: if (isSaltPay) Blockchain.Gnosis else null
|
||||
|
||||
private val tangemNoteBatches = mapOf(
|
||||
"AB01" to Blockchain.Bitcoin,
|
||||
|
|
@ -63,24 +80,6 @@ object TapWorkarounds {
|
|||
|
||||
fun Card.getTangemNoteBlockchain(): Blockchain? = tangemNoteBatches[batchId] ?: null
|
||||
|
||||
|
||||
val Card.isSaltPay: Boolean
|
||||
get() = isSaltPayVisa || isSaltPayWallet
|
||||
|
||||
val Card.isSaltPayVisa: Boolean
|
||||
get() = SaltPayWorkaround.isVisaBatchId(batchId)
|
||||
|
||||
val Card.isSaltPayWallet: Boolean
|
||||
get() = SaltPayWorkaround.isWalletCardId(cardId)
|
||||
|
||||
|
||||
val Card.isExcluded: Boolean
|
||||
get() {
|
||||
val excludedBatch = excludedBatches.contains(batchId)
|
||||
val excludedIssuerName = excludedIssuers.contains(issuer.name.uppercase(Locale.ROOT))
|
||||
return excludedBatch || excludedIssuerName
|
||||
}
|
||||
|
||||
private val excludedBatches = listOf(
|
||||
"0027",
|
||||
"0030",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package com.tangem.domain.common
|
||||
|
||||
import com.tangem.common.card.Card
|
||||
import com.tangem.crypto.CryptoUtils
|
||||
|
||||
class TwinsHelper {
|
||||
|
|
@ -57,14 +56,14 @@ enum class TwinCardNumber(val number: Int) {
|
|||
}
|
||||
|
||||
@Deprecated("Use ScanResponse.isTangemTwin")
|
||||
fun Card.isTangemTwin(): Boolean {
|
||||
fun CardDTO.isTangemTwin(): Boolean {
|
||||
return TwinsHelper.getTwinCardNumber(cardId) != null
|
||||
}
|
||||
|
||||
fun Card.getTwinCardNumber(): TwinCardNumber? {
|
||||
fun CardDTO.getTwinCardNumber(): TwinCardNumber? {
|
||||
return TwinsHelper.getTwinCardNumber(this.cardId)
|
||||
}
|
||||
|
||||
fun Card.getTwinCardIdForUser(): String {
|
||||
fun CardDTO.getTwinCardIdForUser(): String {
|
||||
return TwinsHelper.getTwinCardIdForUser(this.cardId)
|
||||
}
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
package com.tangem.domain.common.extensions
|
||||
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.common.card.Card
|
||||
import com.tangem.common.card.EllipticCurve
|
||||
import com.tangem.common.card.FirmwareVersion
|
||||
import com.tangem.domain.common.CardDTO
|
||||
import com.tangem.domain.common.TapWorkarounds.isTestCard
|
||||
|
||||
/**
|
||||
|
|
@ -12,11 +12,12 @@ import com.tangem.domain.common.TapWorkarounds.isTestCard
|
|||
val FirmwareVersion.Companion.SolanaTokensAvailable
|
||||
get() = FirmwareVersion(4, 52)
|
||||
|
||||
fun Card.supportedBlockchains(): List<Blockchain> {
|
||||
fun CardDTO.supportedBlockchains(): List<Blockchain> {
|
||||
val supportedBlockchains = when {
|
||||
firmwareVersion < FirmwareVersion.MultiWalletAvailable -> {
|
||||
Blockchain.fromCurve(EllipticCurve.Secp256k1)
|
||||
}
|
||||
|
||||
else -> {
|
||||
(Blockchain.fromCurve(EllipticCurve.Secp256k1) + Blockchain.fromCurve(EllipticCurve.Ed25519)).distinct()
|
||||
}
|
||||
|
|
@ -26,7 +27,7 @@ fun Card.supportedBlockchains(): List<Blockchain> {
|
|||
.filter { it.isSupportedInApp() }
|
||||
}
|
||||
|
||||
fun Card.supportedTokens(): List<Blockchain> {
|
||||
fun CardDTO.supportedTokens(): List<Blockchain> {
|
||||
val tokensSupportedByBlockchain = supportedBlockchains().filter { it.canHandleTokens() }.toMutableList()
|
||||
val tokensSupportedByCard = when {
|
||||
firmwareVersion >= FirmwareVersion.SolanaTokensAvailable -> tokensSupportedByBlockchain
|
||||
|
|
@ -41,10 +42,10 @@ fun Card.supportedTokens(): List<Blockchain> {
|
|||
return filtered
|
||||
}
|
||||
|
||||
fun Card.canHandleBlockchain(blockchain: Blockchain): Boolean {
|
||||
fun CardDTO.canHandleBlockchain(blockchain: Blockchain): Boolean {
|
||||
return this.supportedBlockchains().contains(blockchain)
|
||||
}
|
||||
|
||||
fun Card.canHandleToken(blockchain: Blockchain): Boolean {
|
||||
fun CardDTO.canHandleToken(blockchain: Blockchain): Boolean {
|
||||
return this.supportedTokens().contains(blockchain)
|
||||
}
|
||||
|
|
@ -10,8 +10,8 @@ class UserWalletId(
|
|||
) {
|
||||
val value = stringValue.hexToBytes()
|
||||
|
||||
constructor(walletPublicKey: ByteArray) : this(
|
||||
stringValue = calculateUserWalletId(walletPublicKey).toHexString(),
|
||||
constructor(walletPublicKey: ByteArray?) : this(
|
||||
stringValue = walletPublicKey?.let { calculateUserWalletId(it).toHexString() } ?: "",
|
||||
)
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@ package com.tangem.domain.features.addCustomToken.redux
|
|||
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.DerivationStyle
|
||||
import com.tangem.common.card.Card
|
||||
import com.tangem.common.json.MoshiJsonConverter
|
||||
import com.tangem.domain.AddCustomTokenError
|
||||
import com.tangem.domain.DomainWrapped
|
||||
import com.tangem.domain.common.CardDTO
|
||||
import com.tangem.domain.common.TapWorkarounds.isTestCard
|
||||
import com.tangem.domain.common.extensions.isSupportedInApp
|
||||
import com.tangem.domain.common.extensions.supportedBlockchains
|
||||
|
|
@ -133,7 +133,7 @@ data class AddCustomTokenState(
|
|||
null
|
||||
}
|
||||
|
||||
fun reset(card: Card): AddCustomTokenState {
|
||||
fun reset(card: CardDTO): AddCustomTokenState {
|
||||
return this.copy(
|
||||
appSavedCurrencies = null,
|
||||
onTokenAddCallback = null,
|
||||
|
|
@ -159,7 +159,7 @@ data class AddCustomTokenState(
|
|||
.getConvertedData()
|
||||
}
|
||||
|
||||
fun getNetworks(card: Card, type: CustomTokenType): List<Blockchain> {
|
||||
fun getNetworks(card: CardDTO, type: CustomTokenType): List<Blockchain> {
|
||||
return getNetworksList(card, type)
|
||||
}
|
||||
|
||||
|
|
@ -189,7 +189,7 @@ data class AddCustomTokenState(
|
|||
}.derivationPath(derivationStyleToUse)
|
||||
}
|
||||
|
||||
internal fun createFormFields(card: Card, type: CustomTokenType): List<DataField<*>> {
|
||||
internal fun createFormFields(card: CardDTO, type: CustomTokenType): List<DataField<*>> {
|
||||
return listOf(
|
||||
TokenField(ContractAddress),
|
||||
TokenBlockchainField(Network, getNetworksList(card, type)),
|
||||
|
|
@ -204,7 +204,7 @@ data class AddCustomTokenState(
|
|||
* Serves to determine the networks (blockchains & tokens) that can be selected by Form.Networks.
|
||||
* Blockchain.Unknown - is the default selection
|
||||
*/
|
||||
private fun getNetworksList(card: Card, type: CustomTokenType): List<Blockchain> {
|
||||
private fun getNetworksList(card: CardDTO, type: CustomTokenType): List<Blockchain> {
|
||||
val evmBlockchains = Blockchain.values()
|
||||
.filter { it.isEvm() }
|
||||
.filter { card.isTestCard == it.isTestnet() }
|
||||
|
|
@ -239,7 +239,7 @@ data class AddCustomTokenState(
|
|||
)
|
||||
}
|
||||
|
||||
private fun getSupportedDerivations(card: Card): List<Blockchain> {
|
||||
private fun getSupportedDerivations(card: CardDTO): List<Blockchain> {
|
||||
val evmBlockchains = Blockchain.values()
|
||||
.filter { card.isTestCard == it.isTestnet() && it.isEvm() }
|
||||
.filter { it.isSupportedInApp() }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue