Updated on 2026-08-14

This commit is contained in:
Tangem 2021-10-21 19:19:59 +03:00
parent ed1012d315
commit 5ec60f0cce
7 changed files with 47 additions and 28 deletions

View file

@ -4,5 +4,5 @@ package com.tangem.tap.domain
[REDACTED_AUTHOR]
*/
enum class ProductType {
Note, Wallet, Twin, Other
Note, Wallet, Twins, Other
}

View file

@ -16,7 +16,7 @@ import com.tangem.tap.domain.TapWorkarounds.isExcluded
import com.tangem.tap.domain.TapWorkarounds.isTangemNote
import com.tangem.tap.domain.extensions.getSingleWallet
import com.tangem.tap.domain.tasks.product.ScanResponse
import com.tangem.tap.domain.twins.TwinCardsManager
import com.tangem.tap.domain.twins.TwinsHelper
import com.tangem.tap.domain.twins.isTangemTwin
class ScanNoteTask(val card: Card? = null) : CardSessionRunnable<ScanResponse> {
@ -92,7 +92,7 @@ class ScanNoteTask(val card: Card? = null) : CardSessionRunnable<ScanResponse> {
callback(CompletionResult.Success(ScanResponse(card, ProductType.Other, null)))
return@run
}
val verified = TwinCardsManager.verifyTwinPublicKey(
val verified = TwinsHelper.verifyTwinPublicKey(
readDataResult.data.issuerData, publicKey
)
if (verified) {

View file

@ -45,7 +45,7 @@ private class CreateProductWalletTask(
override fun run(session: CardSession, callback: (result: CompletionResult<CreateWalletResponse>) -> Unit) {
val commandProcessor = when (type) {
ProductType.Note -> CreateWalletTangemNote()
ProductType.Twin -> throw UnsupportedOperationException("Use the TwinCardsManager to create a wallet")
ProductType.Twins -> throw UnsupportedOperationException("Use the TwinCardsManager to create a wallet")
ProductType.Wallet -> CreateWalletTangemWallet()
else -> CreateWalletOtherCards()
}

View file

@ -24,7 +24,7 @@ import com.tangem.tap.domain.TapWorkarounds.isExcluded
import com.tangem.tap.domain.TapWorkarounds.isTangemNote
import com.tangem.tap.domain.TapWorkarounds.isTangemWallet
import com.tangem.tap.domain.extensions.getSingleWallet
import com.tangem.tap.domain.twins.TwinCardsManager
import com.tangem.tap.domain.twins.TwinsHelper
import com.tangem.tap.domain.twins.isTangemTwin
data class ScanResponse(
@ -43,13 +43,17 @@ data class ScanResponse(
fun getPrimaryToken(): Token? {
val cardToken = walletData?.token ?: return null
return Token(
cardToken.name,
cardToken.symbol,
cardToken.contractAddress,
cardToken.decimals,
Blockchain.fromId(walletData.blockchain)
cardToken.name,
cardToken.symbol,
cardToken.contractAddress,
cardToken.decimals,
Blockchain.fromId(walletData.blockchain)
)
}
fun twinsIsTwinned(): Boolean {
return walletData != null && secondTwinPublicKey != null
}
}
class ScanProductTask(val card: Card? = null) : CardSessionRunnable<ScanResponse> {
@ -120,21 +124,21 @@ private class ScanTwinProcessor : ProductCommandProcessor<ScanResponse> {
is CompletionResult.Success -> {
val publicKey = card.getSingleWallet()?.publicKey
if (publicKey == null) {
callback(CompletionResult.Success(ScanResponse(card, ProductType.Twin, null)))
callback(CompletionResult.Success(ScanResponse(card, ProductType.Twins, null)))
return@run
}
val verified = TwinCardsManager.verifyTwinPublicKey(readDataResult.data.issuerData, publicKey)
val verified = TwinsHelper.verifyTwinPublicKey(readDataResult.data.issuerData, publicKey)
if (verified) {
val twinPublicKey = readDataResult.data.issuerData.sliceArray(0 until 65)
val walletData = session.environment.walletData
val response = ScanResponse(card, ProductType.Twin, walletData, twinPublicKey.toHexString())
val response = ScanResponse(card, ProductType.Twins, walletData, twinPublicKey.toHexString())
callback(CompletionResult.Success(response))
} else {
callback(CompletionResult.Success(ScanResponse(card, ProductType.Twin, null)))
callback(CompletionResult.Success(ScanResponse(card, ProductType.Twins, null)))
}
}
is CompletionResult.Failure ->
callback(CompletionResult.Success(ScanResponse(card, ProductType.Twin, null)))
callback(CompletionResult.Success(ScanResponse(card, ProductType.Twins, null)))
}
}
}

View file

@ -11,7 +11,6 @@ import com.tangem.common.KeyPair
import com.tangem.common.core.TangemSdkError
import com.tangem.common.extensions.hexToBytes
import com.tangem.common.extensions.toHexString
import com.tangem.crypto.CryptoUtils
import com.tangem.tap.common.analytics.FirebaseAnalyticsHandler
import com.tangem.tap.common.extensions.readAssetAsString
import com.tangem.tap.domain.tasks.product.ScanResponse
@ -21,7 +20,8 @@ import com.tangem.tap.tangemSdkManager
class TwinCardsManager(private val scanResponse: ScanResponse, context: Context) {
private val currentCardId: String = scanResponse.card.cardId
// private val secondCardId: String? = TwinsHelper.getTwinsCardId(currentCardId)
// private val secondCardId: String? = TwinsHelper.getTwinsCardId(currentCardId)
private val secondCardId: String? = null
private var currentCardPublicKey: String? = null
@ -108,14 +108,6 @@ class TwinCardsManager(private val scanResponse: ScanResponse, context: Context)
}
companion object {
fun verifyTwinPublicKey(issuerData: ByteArray, cardWalletPublicKey: ByteArray?): Boolean {
if (issuerData.size < 65 || cardWalletPublicKey == null) return false
val publicKey = issuerData.sliceArray(0 until 65)
val signedKey = issuerData.sliceArray(65 until issuerData.size)
return CryptoUtils.verify(cardWalletPublicKey, publicKey, signedKey)
}
private fun getIssuerKeys(context: Context, publicKey: String): KeyPair {
val issuer = getIssuers(context).first { it.publicKey == publicKey }
return KeyPair(

View file

@ -1,11 +1,20 @@
package com.tangem.tap.domain.twins
import com.tangem.common.card.Card
import com.tangem.crypto.CryptoUtils
class TwinsHelper {
companion object {
const val TWIN_FILE_NAME = "TwinPublicKey"
fun verifyTwinPublicKey(issuerData: ByteArray, cardWalletPublicKey: ByteArray?): Boolean {
if (issuerData.size < 65 || cardWalletPublicKey == null) return false
val publicKey = issuerData.sliceArray(0 until 65)
val signedKey = issuerData.sliceArray(65 until issuerData.size)
return CryptoUtils.verify(cardWalletPublicKey, publicKey, signedKey)
}
fun getTwinCardNumber(cardId: String): TwinCardNumber? {
return when {
firstCardSeries.map { cardId.startsWith(it) }.contains(true) -> {

View file

@ -12,14 +12,28 @@ import com.tangem.tap.preferencesStorage
class OnboardingHelper {
companion object {
fun isOnboardingCase(response: ScanResponse): Boolean = if (response.card.hasWallets())
preferencesStorage.usedCardsPrefStorage.activationIsStarted(response.card.cardId) else true
fun isOnboardingCase(response: ScanResponse): Boolean {
val cardInfoStorage = preferencesStorage.usedCardsPrefStorage
return when {
response.productType == ProductType.Twins -> {
if (!response.twinsIsTwinned()) {
true
} else {
cardInfoStorage.activationIsStarted(response.card.cardId)
}
}
response.card.hasWallets() -> {
cardInfoStorage.activationIsStarted(response.card.cardId)
}
else -> true
}
}
fun whereToNavigate(scanResponse: ScanResponse): AppScreen {
return when (scanResponse.productType) {
ProductType.Note -> AppScreen.OnboardingNote
ProductType.Wallet -> AppScreen.OnboardingWallet
ProductType.Twin -> AppScreen.OnboardingTwins
ProductType.Twins -> AppScreen.OnboardingTwins
ProductType.Other -> AppScreen.OnboardingOther
}
}