diff --git a/tangem-core/src/main/java/com/tangem/CardManager.kt b/tangem-core/src/main/java/com/tangem/CardManager.kt index 197c82891a..2c74c35b94 100644 --- a/tangem-core/src/main/java/com/tangem/CardManager.kt +++ b/tangem-core/src/main/java/com/tangem/CardManager.kt @@ -122,6 +122,26 @@ class CardManager( runTask(task, cardId, callback) } + /** + * This command will create a new wallet on the card having ‘Empty’ state. + * A key pair WalletPublicKey / WalletPrivateKey is generated and securely stored in the card. + * App will need to obtain Wallet_PublicKey from the response of [CreateWalletCommand] or [ReadCommand] + * and then transform it into an address of corresponding blockchain wallet + * according to a specific blockchain algorithm. + * WalletPrivateKey is never revealed by the card and will be used by [SignCommand] and [CheckWalletCommand]. + * RemainingSignature is set to MaxSignatures. + * + * @property cardId CID, Unique Tangem card ID number. + * @property cvc Optional 3-digit code printed on the card. Required if Use_CVC flag is set in Settings_Mask. + */ + fun createWallet(cardId: String, + cvc: ByteArray? = null, + callback: (result: TaskEvent) -> Unit) { + val createWalletCommand = CreateWalletCommand(cardId) + val task = SingleCommandTask(createWalletCommand) + runTask(task, cardId, callback) + } + /** */ @@ -157,6 +177,6 @@ class CardManager( } private fun fetchCardEnvironment(cardId: String?): CardEnvironment { - return cardEnvironmentRepository[cardId] ?: CardEnvironment() + return cardEnvironmentRepository[cardId] ?: CardEnvironment(cardId = cardId) } } \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/commands/CreateWalletCommand.kt b/tangem-core/src/main/java/com/tangem/commands/CreateWalletCommand.kt new file mode 100644 index 0000000000..416ebad2f6 --- /dev/null +++ b/tangem-core/src/main/java/com/tangem/commands/CreateWalletCommand.kt @@ -0,0 +1,73 @@ +package com.tangem.commands + +import com.tangem.CardEnvironment +import com.tangem.common.apdu.CommandApdu +import com.tangem.common.apdu.Instruction +import com.tangem.common.apdu.ResponseApdu +import com.tangem.common.extensions.calculateSha256 +import com.tangem.common.extensions.hexToBytes +import com.tangem.common.tlv.Tlv +import com.tangem.common.tlv.TlvMapper +import com.tangem.common.tlv.TlvTag +import com.tangem.tasks.TaskError + +class CreateWalletResponse( + /** + * CID, Unique Tangem card ID number. + */ + val cardId: String, + /** + * Current status of the card [1 - Empty, 2 - Loaded, 3- Purged] + */ + val status: CardStatus, + /** + + */ + val walletPublicKey: ByteArray +) : CommandResponse + +/** + * This command will create a new wallet on the card having ‘Empty’ state. + * A key pair WalletPublicKey / WalletPrivateKey is generated and securely stored in the card. + * App will need to obtain Wallet_PublicKey from the response of [CreateWalletCommand] or [ReadCommand] + * and then transform it into an address of corresponding blockchain wallet + * according to a specific blockchain algorithm. + * WalletPrivateKey is never revealed by the card and will be used by [SignCommand] and [CheckWalletCommand]. + * RemainingSignature is set to MaxSignatures. + * + * @property cardId CID, Unique Tangem card ID number. + * @property cvc Optional 3-digit code printed on the card. Required if Use_CVC flag is set in Settings_Mask. + */ +class CreateWalletCommand( + private val cardId: String, + private val cvc: ByteArray? = null +) : CommandSerializer() { + + override fun serialize(cardEnvironment: CardEnvironment): CommandApdu { + val tlvData = mutableListOf( + Tlv(TlvTag.Pin, cardEnvironment.pin1.calculateSha256()), + Tlv(TlvTag.CardId, cardId.hexToBytes()), + Tlv(TlvTag.Pin2, cardEnvironment.pin2.calculateSha256()) + ) + if (cvc != null) { + tlvData.add(Tlv(TlvTag.Cvc, cvc)) + } + + return CommandApdu(Instruction.CreateWallet, tlvData) + } + + override fun deserialize(cardEnvironment: CardEnvironment, responseApdu: ResponseApdu): CreateWalletResponse? { + val tlvData = responseApdu.getTlvData() ?: return null + + return try { + val mapper = TlvMapper(tlvData) + CreateWalletResponse( + cardId = mapper.map(TlvTag.CardId), + status = mapper.map(TlvTag.Status), + walletPublicKey = mapper.map(TlvTag.WalletPublicKey) + ) + } catch (exception: Exception) { + throw TaskError.SerializeCommandError() + } + } +} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/common/tlv/TlvTag.kt b/tangem-core/src/main/java/com/tangem/common/tlv/TlvTag.kt index 491509ae08..ca292d37f4 100644 --- a/tangem-core/src/main/java/com/tangem/common/tlv/TlvTag.kt +++ b/tangem-core/src/main/java/com/tangem/common/tlv/TlvTag.kt @@ -52,7 +52,7 @@ enum class TlvTag(val code: Int) { Pause(0x1C), ManufactureId(0x20), - ManufacturerSignature(0x21), + ManufacturerSignature(0x86), IssuerDataPublicKey(0x30), IssuerTransactionPublicKey(0x31),