Updated on 2026-08-14

This commit is contained in:
Tangem 2023-01-09 14:43:19 +03:00
commit 9ffebc7634
566 changed files with 22478 additions and 5796 deletions

View file

@ -1,7 +1,7 @@
package com.tangem.domain
import com.tangem.common.extensions.VoidCallback
import com.tangem.network.api.tangemTech.CoinsResponse
import com.tangem.datasource.api.tangemTech.CoinsResponse
/**
[REDACTED_AUTHOR]

View file

@ -0,0 +1,300 @@
package com.tangem.domain.common
import com.squareup.moshi.JsonClass
import com.tangem.common.card.Card
import com.tangem.common.card.CardWallet
import com.tangem.common.card.EllipticCurve
import com.tangem.common.card.EncryptionMode
import com.tangem.common.hdWallet.DerivationPath
import com.tangem.common.hdWallet.ExtendedPublicKey
import com.tangem.operations.attestation.Attestation
import java.util.*
import com.tangem.common.card.FirmwareVersion as SdkFirmwareVersion
/**
* [Card] copy
* */
@JsonClass(generateAdapter = true)
data class CardDTO(
val cardId: String,
val batchId: String,
val cardPublicKey: ByteArray,
val firmwareVersion: FirmwareVersion,
val manufacturer: Manufacturer,
val issuer: Issuer,
val settings: Settings,
val linkedTerminalStatus: LinkedTerminalStatus,
val isAccessCodeSet: Boolean,
val isPasscodeSet: Boolean?,
val supportedCurves: List<EllipticCurve>,
val wallets: List<Wallet>,
val attestation: Attestation,
val backupStatus: BackupStatus?,
) {
constructor(card: Card) : this(
cardId = card.cardId,
batchId = card.batchId,
cardPublicKey = card.cardPublicKey,
firmwareVersion = FirmwareVersion(card.firmwareVersion),
manufacturer = Manufacturer(card.manufacturer),
issuer = Issuer(card.issuer),
settings = Settings(card.settings),
linkedTerminalStatus = LinkedTerminalStatus.fromSdkStatus(card.linkedTerminalStatus),
isAccessCodeSet = card.isAccessCodeSet,
isPasscodeSet = card.isPasscodeSet,
supportedCurves = card.supportedCurves,
wallets = card.wallets.map { Wallet(it) },
attestation = card.attestation,
backupStatus = BackupStatus.fromSdkStatus(card.backupStatus),
)
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is CardDTO) return false
if (cardId != other.cardId) return false
if (batchId != other.batchId) return false
if (!cardPublicKey.contentEquals(other.cardPublicKey)) return false
if (firmwareVersion != other.firmwareVersion) return false
if (manufacturer != other.manufacturer) return false
if (issuer != other.issuer) return false
if (settings != other.settings) return false
if (linkedTerminalStatus != other.linkedTerminalStatus) return false
if (isAccessCodeSet != other.isAccessCodeSet) return false
if (isPasscodeSet != other.isPasscodeSet) return false
if (supportedCurves != other.supportedCurves) return false
if (wallets != other.wallets) return false
if (attestation != other.attestation) return false
return true
}
override fun hashCode(): Int {
var result = cardId.hashCode()
result = 31 * result + batchId.hashCode()
result = 31 * result + cardPublicKey.contentHashCode()
result = 31 * result + firmwareVersion.hashCode()
result = 31 * result + manufacturer.hashCode()
result = 31 * result + issuer.hashCode()
result = 31 * result + settings.hashCode()
result = 31 * result + linkedTerminalStatus.hashCode()
result = 31 * result + isAccessCodeSet.hashCode()
result = 31 * result + (isPasscodeSet?.hashCode() ?: 0)
result = 31 * result + supportedCurves.hashCode()
result = 31 * result + wallets.hashCode()
result = 31 * result + attestation.hashCode()
return result
}
@JsonClass(generateAdapter = true)
data class Settings(
val securityDelay: Int,
val maxWalletsCount: Int,
val isSettingAccessCodeAllowed: Boolean,
val isSettingPasscodeAllowed: Boolean,
val isResettingUserCodesAllowed: Boolean,
val isLinkedTerminalEnabled: Boolean,
val isBackupAllowed: Boolean,
val supportedEncryptionModes: List<EncryptionMode>,
val isFilesAllowed: Boolean,
val isHDWalletAllowed: Boolean,
) {
constructor(settings: Card.Settings) : this(
securityDelay = settings.securityDelay,
maxWalletsCount = settings.maxWalletsCount,
isSettingAccessCodeAllowed = settings.isSettingAccessCodeAllowed,
isSettingPasscodeAllowed = settings.isSettingPasscodeAllowed,
isResettingUserCodesAllowed = settings.isResettingUserCodesAllowed,
isLinkedTerminalEnabled = settings.isLinkedTerminalEnabled,
isBackupAllowed = settings.isBackupAllowed,
supportedEncryptionModes = settings.supportedEncryptionModes,
isFilesAllowed = settings.isFilesAllowed,
isHDWalletAllowed = settings.isHDWalletAllowed,
)
}
@JsonClass(generateAdapter = true)
data class FirmwareVersion(
val major: Int,
val minor: Int,
val patch: Int,
val type: SdkFirmwareVersion.FirmwareType,
) : Comparable<SdkFirmwareVersion> {
constructor(firmwareVersion: SdkFirmwareVersion) : this(
major = firmwareVersion.major,
minor = firmwareVersion.minor,
patch = firmwareVersion.patch,
type = firmwareVersion.type,
)
val stringValue: String
get() = StringBuilder()
.append("$major.$minor")
.append(if (patch != 0) ".$patch" else "")
.append(type.rawValue ?: "")
.toString()
override fun compareTo(other: SdkFirmwareVersion): Int = when {
major != other.major -> major.compareTo(other.major)
minor != other.minor -> minor.compareTo(other.minor)
else -> patch.compareTo(other.patch)
}
}
@JsonClass(generateAdapter = true)
data class Manufacturer(
val name: String,
val manufactureDate: Date,
val signature: ByteArray?,
) {
constructor(manufacturer: Card.Manufacturer) : this(
name = manufacturer.name,
manufactureDate = manufacturer.manufactureDate,
signature = manufacturer.signature,
)
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is Manufacturer) return false
if (name != other.name) return false
if (manufactureDate != other.manufactureDate) return false
if (signature != null) {
if (other.signature == null) return false
if (!signature.contentEquals(other.signature)) return false
} else if (other.signature != null) return false
return true
}
override fun hashCode(): Int {
var result = name.hashCode()
result = 31 * result + manufactureDate.hashCode()
result = 31 * result + (signature?.contentHashCode() ?: 0)
return result
}
}
@JsonClass(generateAdapter = true)
data class Issuer(
val name: String,
val publicKey: ByteArray,
) {
constructor(issuer: Card.Issuer) : this(
name = issuer.name,
publicKey = issuer.publicKey,
)
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is Issuer) return false
if (name != other.name) return false
if (!publicKey.contentEquals(other.publicKey)) return false
return true
}
override fun hashCode(): Int {
var result = name.hashCode()
result = 31 * result + publicKey.contentHashCode()
return result
}
}
@JsonClass(generateAdapter = true)
data class Wallet(
val publicKey: ByteArray,
val chainCode: ByteArray?,
val curve: EllipticCurve,
val settings: CardWallet.Settings,
val totalSignedHashes: Int?,
val remainingSignatures: Int?,
val index: Int,
val hasBackup: Boolean,
val derivedKeys: Map<DerivationPath, ExtendedPublicKey>,
val extendedPublicKey: ExtendedPublicKey?,
) {
constructor(wallet: CardWallet) : this(
publicKey = wallet.publicKey,
chainCode = wallet.chainCode,
curve = wallet.curve,
settings = wallet.settings,
totalSignedHashes = wallet.totalSignedHashes,
remainingSignatures = wallet.remainingSignatures,
index = wallet.index,
hasBackup = wallet.hasBackup,
derivedKeys = wallet.derivedKeys,
extendedPublicKey = wallet.extendedPublicKey,
)
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is Wallet) return false
if (!publicKey.contentEquals(other.publicKey)) return false
if (chainCode != null) {
if (other.chainCode == null) return false
if (!chainCode.contentEquals(other.chainCode)) return false
} else if (other.chainCode != null) return false
if (curve != other.curve) return false
if (settings != other.settings) return false
if (totalSignedHashes != other.totalSignedHashes) return false
if (remainingSignatures != other.remainingSignatures) return false
if (index != other.index) return false
if (hasBackup != other.hasBackup) return false
return true
}
override fun hashCode(): Int {
var result = publicKey.contentHashCode()
result = 31 * result + (chainCode?.contentHashCode() ?: 0)
result = 31 * result + curve.hashCode()
result = 31 * result + settings.hashCode()
result = 31 * result + (totalSignedHashes ?: 0)
result = 31 * result + (remainingSignatures ?: 0)
result = 31 * result + index
result = 31 * result + hasBackup.hashCode()
return result
}
}
enum class LinkedTerminalStatus {
Current,
Other,
None;
companion object {
internal fun fromSdkStatus(sdkStatus: Card.LinkedTerminalStatus): LinkedTerminalStatus {
return when (sdkStatus) {
Card.LinkedTerminalStatus.Current -> Current
Card.LinkedTerminalStatus.Other -> Other
Card.LinkedTerminalStatus.None -> None
}
}
}
}
sealed class BackupStatus {
data class CardLinked(val cardCount: Int) : BackupStatus()
data class Active(val cardCount: Int) : BackupStatus()
object NoBackup : BackupStatus()
val isActive: Boolean
get() = this is Active || this is CardLinked
companion object {
internal fun fromSdkStatus(sdkStatus: Card.BackupStatus?): BackupStatus? {
return when (sdkStatus) {
is Card.BackupStatus.NoBackup -> NoBackup
is Card.BackupStatus.CardLinked -> CardLinked(sdkStatus.cardCount)
is Card.BackupStatus.Active -> Active(sdkStatus.cardCount)
null -> null
}
}
}
}
}

View file

@ -0,0 +1,14 @@
package com.tangem.domain.common
import com.tangem.common.card.WalletData
import com.tangem.operations.backup.PrimaryCard
import com.tangem.operations.derivation.ExtendedPublicKeysMap
data class CardInfo(
val card: CardDTO,
val productType: ProductType,
val walletData: WalletData?,
val secondTwinPublicKey: String?,
val derivedKeys: Map<KeyWalletPublicKey, ExtendedPublicKeysMap>,
val primaryCard: PrimaryCard?,
)

View file

@ -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
@ -24,7 +23,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,
@ -69,7 +68,7 @@ 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) -> {
@ -82,7 +81,7 @@ data class ScanResponse(
}
}
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
@ -95,13 +94,4 @@ enum class ProductType {
Note, Twins, Wallet, SaltPay, Start2Coin
}
val Card.productType: ProductType
get() = when {
isTangemTwins -> ProductType.Twins
isTangemNote -> ProductType.Note
isSaltPay -> ProductType.SaltPay
isStart2Coin -> ProductType.Start2Coin
else -> ProductType.Wallet
}
typealias KeyWalletPublicKey = ByteArrayKey

View file

@ -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",

View file

@ -1,6 +1,5 @@
package com.tangem.domain.common
import com.tangem.common.card.Card
import com.tangem.crypto.CryptoUtils
class TwinsHelper {
@ -15,18 +14,10 @@ class TwinsHelper {
return CryptoUtils.verify(cardWalletPublicKey, publicKey, signedKey)
}
fun getTwinCardNumber(cardId: String): TwinCardNumber? {
return when {
firstCardSeries.map { cardId.startsWith(it) }.contains(true) -> {
TwinCardNumber.First
}
secondCardSeries.map { cardId.startsWith(it) }.contains(true) -> {
TwinCardNumber.Second
}
else -> {
null
}
}
fun getTwinCardNumber(cardId: String): TwinCardNumber? = when {
firstCardSeries.any(cardId::startsWith) -> TwinCardNumber.First
secondCardSeries.any(cardId::startsWith) -> TwinCardNumber.Second
else -> null
}
fun getPairCardSeries(cardId: String): String? {
@ -65,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)
}

View file

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

View file

@ -1,8 +1,8 @@
package com.tangem.domain.common.extensions
import com.tangem.common.services.Result
import com.tangem.network.api.tangemTech.CoinsResponse
import com.tangem.network.api.tangemTech.TangemTechService
import com.tangem.datasource.api.tangemTech.CoinsResponse
import com.tangem.datasource.api.tangemTech.TangemTechService
suspend fun TangemTechService.getTokens(
contractAddress: String,

View file

@ -0,0 +1,33 @@
package com.tangem.domain.common.util
import com.tangem.common.extensions.hexToBytes
import com.tangem.common.extensions.toHexString
class UserWalletId(
val stringValue: String,
) {
val value = stringValue.hexToBytes()
constructor(value: ByteArray?) : this(
stringValue = value?.toHexString() ?: "",
)
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is UserWalletId) return false
if (stringValue != other.stringValue) return false
return true
}
override fun hashCode(): Int {
return stringValue.hashCode()
}
override fun toString(): String {
return with(stringValue) {
"UserWalletId(${take(3)}...${takeLast(3)})"
}
}
}

View file

@ -2,8 +2,8 @@ package com.tangem.domain.features.addCustomToken
import com.tangem.common.services.Result
import com.tangem.domain.common.extensions.getTokens
import com.tangem.network.api.tangemTech.CoinsResponse
import com.tangem.network.api.tangemTech.TangemTechService
import com.tangem.datasource.api.tangemTech.CoinsResponse
import com.tangem.datasource.api.tangemTech.TangemTechService
/**
[REDACTED_AUTHOR]

View file

@ -8,7 +8,7 @@ import com.tangem.domain.common.form.Field
import com.tangem.domain.common.form.FieldId
import com.tangem.domain.features.addCustomToken.CustomCurrency
import com.tangem.domain.features.addCustomToken.CustomTokenFieldId
import com.tangem.network.api.tangemTech.CoinsResponse
import com.tangem.datasource.api.tangemTech.CoinsResponse
import org.rekotlin.Action
/**

View file

@ -56,7 +56,7 @@ import com.tangem.domain.redux.domainStore
import com.tangem.domain.redux.extensions.dispatchOnMain
import com.tangem.domain.redux.global.DomainGlobalAction
import com.tangem.domain.redux.global.DomainGlobalState
import com.tangem.network.api.tangemTech.CoinsResponse
import com.tangem.datasource.api.tangemTech.CoinsResponse
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

View file

@ -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
@ -37,7 +37,7 @@ import com.tangem.domain.features.addCustomToken.TokenDerivationPathField
import com.tangem.domain.features.addCustomToken.TokenField
import com.tangem.domain.redux.DomainState
import com.tangem.domain.redux.state.StringActionStateConverter
import com.tangem.network.api.tangemTech.CoinsResponse
import com.tangem.datasource.api.tangemTech.CoinsResponse
import org.rekotlin.Action
import org.rekotlin.StateType
@ -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() }

View file

@ -5,7 +5,7 @@ import com.tangem.common.extensions.toHexString
import com.tangem.domain.redux.BaseStoreHub
import com.tangem.domain.redux.DomainState
import com.tangem.domain.redux.ReStoreReducer
import com.tangem.network.common.CardPublicKeyHttpInterceptor
import com.tangem.datasource.api.common.CardPublicKeyHttpInterceptor
import org.rekotlin.Action
/**

View file

@ -3,8 +3,8 @@ package com.tangem.domain.redux.global
import com.tangem.domain.DomainDialog
import com.tangem.domain.common.LogConfig
import com.tangem.domain.common.ScanResponse
import com.tangem.network.api.paymentology.PaymentologyApiService
import com.tangem.network.api.tangemTech.TangemTechService
import com.tangem.datasource.api.paymentology.PaymentologyApiService
import com.tangem.datasource.api.tangemTech.TangemTechService
/**
[REDACTED_AUTHOR]
@ -19,6 +19,8 @@ data class DomainGlobalState(
)
data class NetworkServices(
val tangemTechService: TangemTechService = TangemTechService(LogConfig.network.tangemTechService),
val paymentologyService: PaymentologyApiService = PaymentologyApiService(LogConfig.network.paymentologyApiService),
val tangemTechService: TangemTechService = TangemTechService(
LogConfig.network.tangemTechService),
val paymentologyService: PaymentologyApiService = PaymentologyApiService(
LogConfig.network.paymentologyApiService),
)