Updated on 2026-08-14
This commit is contained in:
parent
ed1012d315
commit
5ec60f0cce
7 changed files with 47 additions and 28 deletions
|
|
@ -4,5 +4,5 @@ package com.tangem.tap.domain
|
|||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
enum class ProductType {
|
||||
Note, Wallet, Twin, Other
|
||||
Note, Wallet, Twins, Other
|
||||
}
|
||||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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) -> {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue