Updated on 2026-08-14

This commit is contained in:
Tangem 2020-01-21 18:01:51 +03:00
parent 9f3ebb2e4c
commit 1a382ce0e6
3 changed files with 95 additions and 2 deletions

View file

@ -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<CreateWalletResponse>) -> 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)
}
}

View file

@ -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<CreateWalletResponse>() {
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()
}
}
}

View file

@ -52,7 +52,7 @@ enum class TlvTag(val code: Int) {
Pause(0x1C),
ManufactureId(0x20),
ManufacturerSignature(0x21),
ManufacturerSignature(0x86),
IssuerDataPublicKey(0x30),
IssuerTransactionPublicKey(0x31),