Updated on 2026-08-14
This commit is contained in:
parent
9b6de19ebe
commit
ce602107bb
16 changed files with 178 additions and 115 deletions
|
|
@ -85,11 +85,15 @@ class TangemSdkManager(
|
|||
).also { sendScanResultsToAnalytics(it) }
|
||||
}
|
||||
|
||||
suspend fun createProductWallet(scanResponse: ScanResponse): CompletionResult<CreateProductWalletTaskResponse> {
|
||||
suspend fun createProductWallet(
|
||||
scanResponse: ScanResponse,
|
||||
shouldReset: Boolean = false,
|
||||
): CompletionResult<CreateProductWalletTaskResponse> {
|
||||
return runTaskAsync(
|
||||
runnable = CreateProductWalletTask(
|
||||
cardTypesResolver = scanResponse.cardTypesResolver,
|
||||
derivationStyleProvider = scanResponse.derivationStyleProvider,
|
||||
shouldReset = shouldReset,
|
||||
),
|
||||
cardId = scanResponse.card.cardId,
|
||||
initialMessage = Message(resources.getString(R.string.initial_message_create_wallet_body)),
|
||||
|
|
@ -100,6 +104,7 @@ class TangemSdkManager(
|
|||
suspend fun importWallet(
|
||||
scanResponse: ScanResponse,
|
||||
mnemonic: String,
|
||||
shouldReset: Boolean,
|
||||
): CompletionResult<CreateProductWalletTaskResponse> {
|
||||
val defaultMnemonic = try {
|
||||
DefaultMnemonic(mnemonic, tangemSdk.wordlist)
|
||||
|
|
@ -108,9 +113,10 @@ class TangemSdkManager(
|
|||
}
|
||||
return runTaskAsync(
|
||||
CreateProductWalletTask(
|
||||
scanResponse.cardTypesResolver,
|
||||
cardTypesResolver = scanResponse.cardTypesResolver,
|
||||
derivationStyleProvider = scanResponse.derivationStyleProvider,
|
||||
defaultMnemonic,
|
||||
mnemonic = defaultMnemonic,
|
||||
shouldReset = shouldReset,
|
||||
),
|
||||
scanResponse.card.cardId,
|
||||
Message(resources.getString(R.string.initial_message_create_wallet_body)),
|
||||
|
|
|
|||
|
|
@ -1,38 +0,0 @@
|
|||
package com.tangem.tap.domain.tasks
|
||||
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.common.card.Card
|
||||
import com.tangem.common.card.FirmwareVersion
|
||||
import com.tangem.common.core.CardSession
|
||||
import com.tangem.common.core.CardSessionRunnable
|
||||
import com.tangem.common.core.TangemSdkError
|
||||
import com.tangem.common.extensions.guard
|
||||
import com.tangem.operations.PreflightReadMode
|
||||
import com.tangem.operations.PreflightReadTask
|
||||
import com.tangem.operations.wallet.CreateWalletTask
|
||||
|
||||
@Deprecated("Use CreateProductWalletAndRescanTask instead")
|
||||
class CreateWalletAndRescanTask : CardSessionRunnable<Card> {
|
||||
|
||||
override fun run(session: CardSession, callback: (result: CompletionResult<Card>) -> Unit) {
|
||||
val card = session.environment.card.guard {
|
||||
callback(CompletionResult.Failure(TangemSdkError.CardError()))
|
||||
return
|
||||
}
|
||||
val firmwareVersion = card.firmwareVersion
|
||||
|
||||
val task = if (firmwareVersion < FirmwareVersion.MultiWalletAvailable) {
|
||||
CreateWalletTask(card.supportedCurves.first())
|
||||
} else {
|
||||
CreateWalletsTask()
|
||||
}
|
||||
|
||||
task.run(session) { result ->
|
||||
when (result) {
|
||||
is CompletionResult.Success ->
|
||||
PreflightReadTask(PreflightReadMode.FullCardRead).run(session, callback)
|
||||
is CompletionResult.Failure -> callback(CompletionResult.Failure(result.error))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
package com.tangem.tap.domain.tasks
|
||||
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.common.card.Card
|
||||
import com.tangem.common.card.EllipticCurve
|
||||
import com.tangem.common.core.CardSession
|
||||
import com.tangem.common.core.CardSessionRunnable
|
||||
import com.tangem.operations.PreflightReadMode
|
||||
import com.tangem.operations.PreflightReadTask
|
||||
import com.tangem.operations.wallet.CreateWalletTask
|
||||
|
||||
@Deprecated("Use CreateProductWalletTask instead")
|
||||
class CreateWalletsTask(curves: List<EllipticCurve>? = null) : CardSessionRunnable<Card> {
|
||||
|
||||
private val curves = curves ?: listOf(
|
||||
EllipticCurve.Secp256k1,
|
||||
EllipticCurve.Ed25519,
|
||||
EllipticCurve.Secp256r1,
|
||||
)
|
||||
|
||||
private var index = 0
|
||||
|
||||
override fun run(session: CardSession, callback: (result: CompletionResult<Card>) -> Unit) {
|
||||
val curve = curves[index]
|
||||
createWallet(curve, session, callback)
|
||||
}
|
||||
|
||||
private fun createWallet(
|
||||
curve: EllipticCurve,
|
||||
session: CardSession,
|
||||
callback: (result: CompletionResult<Card>) -> Unit,
|
||||
) {
|
||||
CreateWalletTask(curve).run(session) { result ->
|
||||
when (result) {
|
||||
is CompletionResult.Success -> {
|
||||
if (index == curves.lastIndex) {
|
||||
PreflightReadTask(PreflightReadMode.FullCardRead).run(session, callback)
|
||||
return@run
|
||||
}
|
||||
index += 1
|
||||
createWallet(curves[index], session, callback)
|
||||
}
|
||||
is CompletionResult.Failure -> {
|
||||
callback(CompletionResult.Failure(result.error))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.tangem.tap.domain.tasks.product
|
||||
|
||||
import com.tangem.common.card.CardWallet
|
||||
import com.tangem.common.card.EllipticCurve
|
||||
|
||||
class CardInitializationValidator(private val expectedCurves: List<EllipticCurve>) {
|
||||
|
||||
fun validateWallets(wallets: List<CardWallet>): Boolean {
|
||||
val curves = wallets.map { it.curve }.toSet()
|
||||
return curves.size == expectedCurves.size &&
|
||||
curves.containsAll(expectedCurves)
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ import com.tangem.blockchain.common.Blockchain
|
|||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.common.card.Card
|
||||
import com.tangem.common.card.EllipticCurve
|
||||
import com.tangem.common.card.FirmwareVersion
|
||||
import com.tangem.common.core.CardSession
|
||||
import com.tangem.common.core.CardSessionRunnable
|
||||
import com.tangem.common.core.TangemSdkError
|
||||
|
|
@ -24,6 +25,7 @@ import com.tangem.operations.backup.PrimaryCard
|
|||
import com.tangem.operations.backup.StartPrimaryCardLinkingCommand
|
||||
import com.tangem.operations.derivation.DeriveMultipleWalletPublicKeysTask
|
||||
import com.tangem.operations.derivation.ExtendedPublicKeysMap
|
||||
import com.tangem.operations.read.ReadWalletsListCommand
|
||||
import com.tangem.operations.wallet.CreateWalletTask
|
||||
import com.tangem.tap.features.demo.DemoHelper
|
||||
import com.tangem.operations.wallet.CreateWalletResponse as SdkCreateWalletResponse
|
||||
|
|
@ -60,6 +62,7 @@ class CreateProductWalletTask(
|
|||
private val cardTypesResolver: CardTypesResolver,
|
||||
private val derivationStyleProvider: DerivationStyleProvider,
|
||||
private val mnemonic: Mnemonic? = null,
|
||||
private val shouldReset: Boolean,
|
||||
) : CardSessionRunnable<CreateProductWalletTaskResponse> {
|
||||
|
||||
override val allowsRequestAccessCodeFromRepository: Boolean = false
|
||||
|
|
@ -79,7 +82,7 @@ class CreateProductWalletTask(
|
|||
cardTypesResolver.isTangemTwins() ->
|
||||
throw UnsupportedOperationException("Use the TwinCardsManager to create a wallet")
|
||||
|
||||
else -> CreateWalletTangemWallet(mnemonic, derivationStyleProvider)
|
||||
else -> CreateWalletTangemWallet(mnemonic, shouldReset, derivationStyleProvider, cardDto)
|
||||
}
|
||||
commandProcessor.proceed(cardDto, session) {
|
||||
when (it) {
|
||||
|
|
@ -139,38 +142,38 @@ private class CreateWalletTangemNote(private val cardTypesResolver: CardTypesRes
|
|||
*/
|
||||
private class CreateWalletTangemWallet(
|
||||
private val mnemonic: Mnemonic?,
|
||||
private val shouldReset: Boolean,
|
||||
private val derivationStyleProvider: DerivationStyleProvider,
|
||||
cardDTO: CardDTO,
|
||||
) : ProductCommandProcessor<CreateProductWalletTaskResponse> {
|
||||
|
||||
private var primaryCard: PrimaryCard? = null
|
||||
private val cardConfig = CardConfig.createConfig(cardDTO)
|
||||
|
||||
override fun proceed(
|
||||
card: CardDTO,
|
||||
session: CardSession,
|
||||
callback: (result: CompletionResult<CreateProductWalletTaskResponse>) -> Unit,
|
||||
) {
|
||||
val config = CardConfig.createConfig(card)
|
||||
val walletsOnCard = card.wallets.map { it.curve }.toSet()
|
||||
val curves = config.mandatoryCurves.toSet()
|
||||
.intersect(card.supportedCurves.toSet())
|
||||
.subtract(walletsOnCard).toList()
|
||||
|
||||
if (curves.isEmpty()) {
|
||||
val createWalletResponses = card.wallets.map { wallet ->
|
||||
CreateWalletResponse(card.cardId, wallet)
|
||||
}
|
||||
proceedWithCreatedWallets(card, createWalletResponses, session, callback)
|
||||
return
|
||||
if (walletsOnCard.isEmpty()) {
|
||||
createMultiWallet(card, session, callback)
|
||||
} else if (shouldReset) {
|
||||
resetCard(card, session, callback)
|
||||
} else {
|
||||
callback(CompletionResult.Failure(TangemSdkError.WalletAlreadyCreated()))
|
||||
}
|
||||
CreateWalletsTask(curves, mnemonic).run(session) { result ->
|
||||
}
|
||||
|
||||
private fun createMultiWallet(
|
||||
card: CardDTO,
|
||||
session: CardSession,
|
||||
callback: (result: CompletionResult<CreateProductWalletTaskResponse>) -> Unit,
|
||||
) {
|
||||
CreateWalletsTask(cardConfig.mandatoryCurves, mnemonic).run(session) { result ->
|
||||
when (result) {
|
||||
is CompletionResult.Success -> {
|
||||
proceedWithCreatedWallets(
|
||||
card = card,
|
||||
createWalletResponses = result.data.createWalletResponses.map { CreateWalletResponse(it) },
|
||||
session = session,
|
||||
callback = callback,
|
||||
)
|
||||
checkIfAllWalletsCreated(card, session, result.data, callback)
|
||||
}
|
||||
is CompletionResult.Failure -> {
|
||||
callback(CompletionResult.Failure(result.error))
|
||||
|
|
@ -179,6 +182,61 @@ private class CreateWalletTangemWallet(
|
|||
}
|
||||
}
|
||||
|
||||
private fun checkIfAllWalletsCreated(
|
||||
card: CardDTO,
|
||||
session: CardSession,
|
||||
createResponse: CreateWalletsResponse,
|
||||
callback: (result: CompletionResult<CreateProductWalletTaskResponse>) -> Unit,
|
||||
) {
|
||||
if (card.firmwareVersion < FirmwareVersion.MultiWalletAvailable) {
|
||||
proceedWithCreatedWallets(
|
||||
card = card,
|
||||
createWalletResponses = createResponse.createWalletResponses.map { CreateWalletResponse(it) },
|
||||
session = session,
|
||||
callback = callback,
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
val command = ReadWalletsListCommand()
|
||||
command.run(session) { response ->
|
||||
when (response) {
|
||||
is CompletionResult.Success -> {
|
||||
val cardInitializationValidator = CardInitializationValidator(cardConfig.mandatoryCurves)
|
||||
if (cardInitializationValidator.validateWallets(response.data.wallets)) {
|
||||
proceedWithCreatedWallets(
|
||||
card = card,
|
||||
createWalletResponses = createResponse.createWalletResponses.map {
|
||||
CreateWalletResponse(it)
|
||||
},
|
||||
session = session,
|
||||
callback = callback,
|
||||
)
|
||||
} else {
|
||||
callback(CompletionResult.Failure(TangemSdkError.WalletAlreadyCreated()))
|
||||
}
|
||||
}
|
||||
is CompletionResult.Failure -> callback(CompletionResult.Failure(response.error))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun resetCard(
|
||||
card: CardDTO,
|
||||
session: CardSession,
|
||||
callback: (result: CompletionResult<CreateProductWalletTaskResponse>) -> Unit,
|
||||
) {
|
||||
val resetCommand = ResetToFactorySettingsTask(allowsRequestAccessCodeFromRepository = false)
|
||||
resetCommand.run(session) {
|
||||
when (it) {
|
||||
is CompletionResult.Success -> {
|
||||
createMultiWallet(card, session, callback)
|
||||
}
|
||||
is CompletionResult.Failure -> callback(CompletionResult.Failure(it.error))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun proceedWithCreatedWallets(
|
||||
card: CardDTO,
|
||||
createWalletResponses: List<CreateWalletResponse>,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue