Updated on 2026-08-14
This commit is contained in:
commit
9ffebc7634
566 changed files with 22478 additions and 5796 deletions
|
|
@ -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]
|
||||
|
|
|
|||
300
domain/src/main/java/com/tangem/domain/common/CardDTO.kt
Normal file
300
domain/src/main/java/com/tangem/domain/common/CardDTO.kt
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
14
domain/src/main/java/com/tangem/domain/common/CardInfo.kt
Normal file
14
domain/src/main/java/com/tangem/domain/common/CardInfo.kt
Normal 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?,
|
||||
)
|
||||
|
|
@ -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
|
||||
|
|
@ -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 {
|
||||
|
|
@ -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)
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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)})"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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() }
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue