Updated on 2026-08-14
This commit is contained in:
commit
7958ae30a6
8 changed files with 72 additions and 36 deletions
|
|
@ -6,7 +6,6 @@ import com.tangem.commands.common.card.CardStatus
|
|||
import com.tangem.commands.common.network.Result
|
||||
import com.tangem.tap.common.analytics.AnalyticsEvent
|
||||
import com.tangem.tap.common.analytics.FirebaseAnalyticsHandler
|
||||
import com.tangem.tap.common.redux.global.CryptoCurrencyName
|
||||
import com.tangem.tap.common.redux.global.FiatCurrencyName
|
||||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
import com.tangem.tap.currenciesRepository
|
||||
|
|
@ -150,11 +149,7 @@ class TapWalletManager {
|
|||
val config = store.state.globalState.configManager?.config ?: return@withContext
|
||||
|
||||
val blockchain = data.card.getBlockchain()
|
||||
val primaryWalletManager = if (blockchain != null) {
|
||||
walletManagerFactory.makeWalletManagerForApp(data.card, blockchain)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
val primaryWalletManager = walletManagerFactory.makePrimaryWalletManager(data)
|
||||
|
||||
if (blockchain != null && primaryWalletManager != null) {
|
||||
val primaryToken = data.card.getToken()
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@ import com.tangem.blockchain.common.WalletManagerFactory
|
|||
import com.tangem.commands.common.card.Card
|
||||
import com.tangem.commands.common.card.EllipticCurve
|
||||
import com.tangem.commands.wallet.CardWallet
|
||||
import com.tangem.common.extensions.hexToBytes
|
||||
import com.tangem.tap.domain.tasks.ScanNoteResponse
|
||||
import com.tangem.tap.domain.twins.isTwinCard
|
||||
|
||||
fun WalletManagerFactory.makeWalletManagerForApp(
|
||||
card: Card,
|
||||
|
|
@ -32,3 +35,24 @@ fun WalletManagerFactory.makeWalletManagersForApp(
|
|||
): List<WalletManager> {
|
||||
return blockchains.mapNotNull { blockchain -> makeWalletManagerForApp(card, blockchain) }
|
||||
}
|
||||
|
||||
fun WalletManagerFactory.makePrimaryWalletManager(
|
||||
data: ScanNoteResponse,
|
||||
): WalletManager? {
|
||||
val card = data.card
|
||||
val blockchain = card.getBlockchain()
|
||||
val supportedCurves = blockchain?.getSupportedCurves() ?: return null
|
||||
val wallets = card.getWallets().filter { wallet -> supportedCurves.contains(wallet.curve) }
|
||||
val wallet = selectWallet(wallets)
|
||||
val publicKey = wallet?.publicKey ?: return null
|
||||
val curveToUse = wallet.curve ?: return null
|
||||
return if (card.isTwinCard() && data.secondTwinPublicKey != null) {
|
||||
makeMultisigWalletManager(
|
||||
cardId = card.cardId,
|
||||
walletPublicKey = publicKey, pairPublicKey = data.secondTwinPublicKey.hexToBytes(),
|
||||
blockchain = blockchain, curve = curveToUse
|
||||
)
|
||||
} else {
|
||||
makeWalletManager(card.cardId, publicKey, blockchain, curveToUse)
|
||||
}
|
||||
}
|
||||
|
|
@ -35,6 +35,4 @@ class CreateWalletAndRescanTask : CardSessionRunnable<Card>, PreflightReadCapabl
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -44,7 +44,7 @@ class ScanNoteTask(val card: Card? = null) : CardSessionRunnable<ScanNoteRespons
|
|||
val card = this.card?.copy(
|
||||
isPin1Default = result.data.isPin1Default,
|
||||
isPin2Default = result.data.isPin2Default
|
||||
) ?: result.data
|
||||
)?.also { it.setWallets(card.getWallets()) } ?: result.data
|
||||
|
||||
val error = getErrorIfExcludedCard(card)
|
||||
if (error != null) {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package com.tangem.tap.domain.twins
|
|||
|
||||
import com.tangem.CardSession
|
||||
import com.tangem.CardSessionRunnable
|
||||
import com.tangem.commands.common.card.CardStatus
|
||||
import com.tangem.commands.wallet.CreateWalletResponse
|
||||
import com.tangem.commands.wallet.PurgeWalletCommand
|
||||
import com.tangem.common.CompletionResult
|
||||
|
|
@ -14,12 +13,15 @@ import com.tangem.tasks.CreateWalletTask
|
|||
class CreateFirstTwinWalletTask : CardSessionRunnable<CreateWalletResponse> {
|
||||
override val requiresPin2 = false
|
||||
|
||||
override fun run(session: CardSession, callback: (result: CompletionResult<CreateWalletResponse>) -> Unit) {
|
||||
override fun run(
|
||||
session: CardSession,
|
||||
callback: (result: CompletionResult<CreateWalletResponse>) -> Unit,
|
||||
) {
|
||||
if (session.environment.card?.getSingleWallet()?.publicKey != null) {
|
||||
PurgeWalletCommand(TangemSdkConstants.getDefaultWalletIndex()).run(session) { response ->
|
||||
when (response) {
|
||||
is CompletionResult.Success -> {
|
||||
session.environment.card = session.environment.card?.copy(status = CardStatus.Empty)
|
||||
session.environment.card = session.environment.card?.changeStatusToEmpty()
|
||||
CreateWalletTask().run(session) { callback(it) }
|
||||
}
|
||||
is CompletionResult.Failure -> callback(CompletionResult.Failure(response.error))
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ package com.tangem.tap.domain.twins
|
|||
import com.tangem.CardSession
|
||||
import com.tangem.CardSessionRunnable
|
||||
import com.tangem.Message
|
||||
import com.tangem.commands.common.card.CardStatus
|
||||
import com.tangem.commands.wallet.CreateWalletResponse
|
||||
import com.tangem.commands.wallet.PurgeWalletCommand
|
||||
import com.tangem.common.CompletionResult
|
||||
|
|
@ -26,8 +25,7 @@ class CreateSecondTwinWalletTask(
|
|||
PurgeWalletCommand(TangemSdkConstants.getDefaultWalletIndex()).run(session) { response ->
|
||||
when (response) {
|
||||
is CompletionResult.Success -> {
|
||||
session.environment.card =
|
||||
session.environment.card?.copy(status = CardStatus.Empty)
|
||||
session.environment.card = session.environment.card?.changeStatusToEmpty()
|
||||
finishTask(session, callback)
|
||||
}
|
||||
is CompletionResult.Failure -> callback(CompletionResult.Failure(response.error))
|
||||
|
|
@ -43,8 +41,8 @@ class CreateSecondTwinWalletTask(
|
|||
CreateWalletTask().run(session) { result ->
|
||||
when (result) {
|
||||
is CompletionResult.Success -> {
|
||||
session.environment.card =
|
||||
session.environment.card?.copy(status = CardStatus.Loaded)
|
||||
session.environment.card = session.environment.card?.changeStatusToLoaded()
|
||||
|
||||
WriteProtectedIssuerDataTask(
|
||||
firstPublicKey.hexToBytes(), TwinCardsManager.issuerKeys
|
||||
).run(session) { writeResult ->
|
||||
|
|
|
|||
|
|
@ -3,27 +3,32 @@ package com.tangem.tap.domain.twins
|
|||
import com.tangem.CardSession
|
||||
import com.tangem.CardSessionRunnable
|
||||
import com.tangem.KeyPair
|
||||
import com.tangem.commands.read.ReadCommand
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.tap.domain.tasks.ScanNoteResponse
|
||||
import com.tangem.tap.domain.tasks.ScanNoteTask
|
||||
import com.tangem.tasks.PreflightReadSettings
|
||||
import com.tangem.tasks.PreflightReadTask
|
||||
|
||||
class FinalizeTwinTask(
|
||||
private val twinPublicKey: ByteArray, private val issuerKeys: KeyPair
|
||||
) : CardSessionRunnable<ScanNoteResponse> {
|
||||
private val twinPublicKey: ByteArray, private val issuerKeys: KeyPair,
|
||||
) : CardSessionRunnable<ScanNoteResponse> {
|
||||
override val requiresPin2 = true
|
||||
|
||||
override fun run(session: CardSession, callback: (result: CompletionResult<ScanNoteResponse>) -> Unit) {
|
||||
override fun run(
|
||||
session: CardSession,
|
||||
callback: (result: CompletionResult<ScanNoteResponse>) -> Unit,
|
||||
) {
|
||||
WriteProtectedIssuerDataTask(twinPublicKey, issuerKeys).run(session) { result ->
|
||||
when (result) {
|
||||
is CompletionResult.Success -> {
|
||||
ReadCommand().run(session) { readResult ->
|
||||
is CompletionResult.Success ->
|
||||
PreflightReadTask(PreflightReadSettings.FullCardRead).run(session) { readResult ->
|
||||
when (readResult) {
|
||||
is CompletionResult.Success -> ScanNoteTask(readResult.data).run(session, callback)
|
||||
is CompletionResult.Failure -> callback(CompletionResult.Failure(readResult.error))
|
||||
is CompletionResult.Success ->
|
||||
ScanNoteTask(readResult.data).run(session, callback)
|
||||
is CompletionResult.Failure ->
|
||||
callback(CompletionResult.Failure(readResult.error))
|
||||
}
|
||||
}
|
||||
}
|
||||
is CompletionResult.Failure -> callback(CompletionResult.Failure(result.error))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
package com.tangem.tap.domain.twins
|
||||
|
||||
import com.tangem.commands.common.card.Card
|
||||
import com.tangem.commands.common.card.CardStatus
|
||||
import com.tangem.commands.common.card.masks.Product
|
||||
import com.tangem.commands.wallet.WalletStatus
|
||||
import com.tangem.tap.common.extensions.isEven
|
||||
|
||||
class TwinsHelper {
|
||||
|
|
@ -53,16 +55,16 @@ class TwinsHelper {
|
|||
|
||||
private fun String.calculateLuhn(): Int {
|
||||
val checksum = this.reversed()
|
||||
.mapIndexed { index, c ->
|
||||
val digit = if (c in '0'..'9') c - '0' else c - 'A'
|
||||
if (!index.isEven()) {
|
||||
digit
|
||||
} else {
|
||||
val newDigit = digit * 2
|
||||
if (newDigit >= 10) newDigit - 9 else newDigit
|
||||
}
|
||||
}.sum()
|
||||
.rem(10)
|
||||
.mapIndexed { index, c ->
|
||||
val digit = if (c in '0'..'9') c - '0' else c - 'A'
|
||||
if (!index.isEven()) {
|
||||
digit
|
||||
} else {
|
||||
val newDigit = digit * 2
|
||||
if (newDigit >= 10) newDigit - 9 else newDigit
|
||||
}
|
||||
}.sum()
|
||||
.rem(10)
|
||||
return (10 - checksum) % 10
|
||||
}
|
||||
|
||||
|
|
@ -81,4 +83,16 @@ fun Card.isTwinCard(): Boolean {
|
|||
|
||||
fun Card.getTwinCardIdForUser(): String {
|
||||
return TwinsHelper.getTwinCardIdForUser(this.cardId)
|
||||
}
|
||||
|
||||
fun Card.changeStatusToLoaded(): Card {
|
||||
val wallets = getWallets().map { it.copy(status = WalletStatus.Loaded) }
|
||||
return copy(status = CardStatus.Loaded)
|
||||
.also { it.setWallets(wallets) }
|
||||
}
|
||||
|
||||
fun Card.changeStatusToEmpty(): Card {
|
||||
val wallets = getWallets().map { it.copy(status = WalletStatus.Empty) }
|
||||
return copy(status = CardStatus.Empty)
|
||||
.also { it.setWallets(wallets) }
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue