Updated on 2026-08-14

This commit is contained in:
Tangem 2020-04-28 22:24:55 +03:00
parent 7b4b9e4ff7
commit a0750c3dbc
7 changed files with 339 additions and 59 deletions

View file

@ -9,6 +9,11 @@ interface DefaultConverter<A, B> {
fun convert(from: A, default: B): B
}
interface TwoWayConverter<A, B> {
fun aToB(from: A): B
fun bToA(from: B): A
}
interface ItemsToModel<M> : DefaultConverter<List<Item>, M>
interface ModelToItems<M> : Converter<M, List<Item>>

View file

@ -16,9 +16,9 @@ class ConfigValuesHolder : BaseTypedHolder<Id, Value>() {
fun init(default: PersonalizationConfig) {
register(CardNumber.Series, Value(default.series))
register(CardNumber.Number, Value(default.startNumber))
register(CardNumber.BatchId, Value(default.batchId))
register(CardNumber.BatchId, Value(default.cardData.batch))
register(Common.Curve, Value(default.curveID, Helper.listOfCurves()))
register(Common.Blockchain, Value(default.blockchain, Helper.listOfBlockchain()))
register(Common.Blockchain, Value(default.cardData.blockchain, Helper.listOfBlockchain()))
register(Common.BlockchainCustom, Value(default.blockchainCustom))
register(Common.MaxSignatures, Value(default.MaxSignatures))
register(Common.CreateWallet, Value(default.createWallet))
@ -35,9 +35,9 @@ class ConfigValuesHolder : BaseTypedHolder<Id, Value>() {
register(SignHashExProp.RequireTerminalTxSig, Value(default.requireTerminalTxSignature))
register(SignHashExProp.CheckPin3, Value(default.checkPIN3onCard))
register(Token.ItsToken, Value(default.itsToken))
register(Token.Symbol, Value(default.symbol))
register(Token.ContractAddress, Value(default.contractAddress))
register(Token.Decimal, Value(default.decimal))
register(Token.Symbol, Value(default.cardData.token_symbol))
register(Token.ContractAddress, Value(default.cardData.token_contract_address))
register(Token.Decimal, Value(default.cardData.token_decimal))
register(ProductMask.Note, Value(default.cardData.product_note))
register(ProductMask.Tag, Value(default.cardData.product_tag))
register(ProductMask.IdCard, Value(default.cardData.product_id_card))

View file

@ -52,9 +52,9 @@ class ItemsToPersonalizationConfig : ItemsToModel<PersonalizationConfig> {
val export = PersonalizationConfig()
export.series = getTyped(CardNumber.Series)
export.startNumber = getTyped(CardNumber.Number)
export.batchId = getTyped(CardNumber.BatchId)
export.cardData.batch = getTyped(CardNumber.BatchId)
export.curveID = getTyped(Common.Curve)
export.blockchain = getTyped(Common.Blockchain)
export.cardData.blockchain = getTyped(Common.Blockchain)
export.blockchainCustom = getTyped(Common.BlockchainCustom)
export.MaxSignatures = getTyped(Common.MaxSignatures)
export.createWallet = getTyped(Common.CreateWallet)
@ -71,9 +71,9 @@ class ItemsToPersonalizationConfig : ItemsToModel<PersonalizationConfig> {
export.requireTerminalTxSignature = getTyped(SignHashExProp.RequireTerminalTxSig)
export.checkPIN3onCard = getTyped(SignHashExProp.CheckPin3)
export.itsToken = getTyped(Token.ItsToken)
export.symbol = getTyped(Token.Symbol)
export.contractAddress = getTyped(Token.ContractAddress)
export.decimal = getTyped(Token.Decimal)
export.cardData.token_symbol = getTyped(Token.Symbol)
export.cardData.token_contract_address = getTyped(Token.ContractAddress)
export.cardData.token_decimal = getTyped(Token.Decimal)
export.cardData = export.cardData.apply { this.product_note = getTyped(ProductMask.Note) }
export.cardData = export.cardData.apply { this.product_tag = getTyped(ProductMask.Tag) }
export.cardData = export.cardData.apply { this.product_id_card = getTyped(ProductMask.IdCard) }

View file

@ -1,6 +1,9 @@
package com.tangem.devkit.ucase.variants.personalize.converter
import com.tangem.commands.*
import com.tangem.commands.CardData
import com.tangem.commands.EllipticCurve
import com.tangem.commands.Product
import com.tangem.commands.ProductMaskBuilder
import com.tangem.commands.personalization.entities.CardConfig
import com.tangem.commands.personalization.entities.NdefRecord
import com.tangem.devkit.ucase.variants.personalize.dto.PersonalizationConfig
@ -10,29 +13,7 @@ import java.util.*
class PersonalizationConfigToCardConfig : Converter<PersonalizationConfig, CardConfig> {
override fun convert(from: PersonalizationConfig): CardConfig {
val signingMethodMaskBuilder = SigningMethodMaskBuilder()
if (from.SigningMethod0) {
signingMethodMaskBuilder.add(SigningMethod.SignHash)
}
if (from.SigningMethod1) {
signingMethodMaskBuilder.add(SigningMethod.SignRaw)
}
if (from.SigningMethod2) {
signingMethodMaskBuilder.add(SigningMethod.SignHashValidateByIssuer)
}
if (from.SigningMethod3) {
signingMethodMaskBuilder.add(SigningMethod.SignRawValidateByIssuer)
}
if (from.SigningMethod4) {
signingMethodMaskBuilder.add(SigningMethod.SignHashValidateByIssuerWriteIssuerData)
}
if (from.SigningMethod5) {
signingMethodMaskBuilder.add(SigningMethod.SignRawValidateByIssuerWriteIssuerData)
}
if (from.SigningMethod6) {
signingMethodMaskBuilder.add(SigningMethod.SignHash)
}
val signingMethod = signingMethodMaskBuilder.build()
val signingMethod = PersonalizationConfig.makeSigningMask(from)
val isNote = from.cardData.product_note
val isTag = from.cardData.product_tag
@ -40,25 +21,25 @@ class PersonalizationConfigToCardConfig : Converter<PersonalizationConfig, CardC
val isIdIssuer = from.cardData.product_id_issuer
val productMaskBuilder = ProductMaskBuilder()
if (isNote) productMaskBuilder.add(com.tangem.commands.Product.Note)
if (isTag) productMaskBuilder.add(com.tangem.commands.Product.Tag)
if (isIdCard) productMaskBuilder.add(com.tangem.commands.Product.IdCard)
if (isIdIssuer) productMaskBuilder.add(com.tangem.commands.Product.IdIssuer)
if (isNote) productMaskBuilder.add(Product.Note)
if (isTag) productMaskBuilder.add(Product.Tag)
if (isIdCard) productMaskBuilder.add(Product.IdCard)
if (isIdIssuer) productMaskBuilder.add(Product.IdIssuer)
val productMask = productMaskBuilder.build()
var tokenSymbol: String? = null
var tokenContractAddress: String? = null
var tokenDecimal: Int? = null
if (from.itsToken) {
tokenSymbol = from.symbol
tokenContractAddress = from.contractAddress
tokenDecimal = from.decimal.toInt()
tokenSymbol = from.cardData.token_symbol
tokenContractAddress = from.cardData.token_contract_address
tokenDecimal = from.cardData.token_decimal
}
val blockchain = if (from.blockchain.isNotEmpty()) from.blockchain else from.blockchainCustom
val blockchain = if (from.cardData.blockchain.isNotEmpty()) from.cardData.blockchain else from.blockchainCustom
val cardData = CardData(
blockchainName = blockchain,
batchId = from.batchId,
batchId = from.cardData.batch,
productMask = productMask,
tokenSymbol = tokenSymbol,
tokenContractAddress = tokenContractAddress,

View file

@ -0,0 +1,189 @@
package com.tangem.devkit.ucase.variants.personalize.converter
import com.tangem.commands.EllipticCurve
import com.tangem.commands.SigningMethod
import com.tangem.commands.SigningMethodMask
import com.tangem.commands.personalization.entities.NdefRecord
import com.tangem.devkit._arch.structure.abstraction.TwoWayConverter
import com.tangem.devkit.ucase.variants.personalize.dto.CardData
import com.tangem.devkit.ucase.variants.personalize.dto.PersonalizationConfig
import com.tangem.devkit.ucase.variants.personalize.dto.PersonalizationJson
import ru.dev.gbixahue.eu4d.lib.kotlin.common.Converter
/**
[REDACTED_AUTHOR]
*/
class PersonalizationJsonConverter : TwoWayConverter<PersonalizationJson, PersonalizationConfig> {
override fun aToB(from: PersonalizationJson): PersonalizationConfig = JsonToConfig().convert(from)
override fun bToA(from: PersonalizationConfig): PersonalizationJson = ConfigToJson().convert(from)
}
internal class JsonToConfig : Converter<PersonalizationJson, PersonalizationConfig> {
override fun convert(from: PersonalizationJson): PersonalizationConfig {
val config = PersonalizationConfig.default()
config.apply {
// Card number
series = from.series
startNumber = from.startNumber
// Common
curveID = EllipticCurve.byName(from.curveID)?.curve ?: ""
blockchainCustom = ""
MaxSignatures = from.MaxSignatures
createWallet = from.createWallet != 0L
// Sign hash external properties
pinLessFloorLimit = 100000L
hexCrExKey = from.hexCrExKey
requireTerminalTxSignature = from.requireTerminalTxSignature
requireTerminalCertSignature = from.requireTerminalCertSignature
checkPIN3onCard = from.checkPIN3onCard
// Product mask
cardData = from.cardData
// Settings mask
isReusable = from.isReusable
useActivation = from.useActivation
forbidPurgeWallet = from.forbidPurgeWallet
allowSelectBlockchain = from.allowSelectBlockchain
useBlock = from.useBlock
useOneCommandAtTime = from.useOneCommandAtTime
useCVC = from.useCVC
allowSwapPIN = from.allowSwapPIN
allowSwapPIN2 = from.allowSwapPIN2
forbidDefaultPIN = from.forbidDefaultPIN
smartSecurityDelay = from.smartSecurityDelay
protectIssuerDataAgainstReplay = from.protectIssuerDataAgainstReplay
skipSecurityDelayIfValidatedByIssuer = from.skipSecurityDelayIfValidatedByIssuer
skipCheckPIN2andCVCIfValidatedByIssuer = from.skipCheckPIN2andCVCIfValidatedByIssuer
skipSecurityDelayIfValidatedByLinkedTerminal = from.skipSecurityDelayIfValidatedByLinkedTerminal
restrictOverwriteIssuerDataEx = from.restrictOverwriteIssuerDataEx
// Settings mask - protocol encryption
protocolAllowUnencrypted = from.protocolAllowUnencrypted
protocolAllowStaticEncryption = from.protocolAllowStaticEncryption
// Settings mask
useNDEF = from.useNDEF
useDynamicNDEF = from.useDynamicNDEF
disablePrecomputedNDEF = from.disablePrecomputedNDEF
// Pins
PIN = from.PIN
PIN2 = from.PIN2
PIN3 = from.PIN3
CVC = from.CVC
pauseBeforePIN2 = from.pauseBeforePIN2
count = from.count
issuerName = from.issuerName
issuerData = from.issuerData
// numberFormat = from.numberFormat
}
fillToken(config, from.cardData)
fillSigningMethod(config, from.SigningMethod)
fillNdef(config, from.ndef)
return config
}
private fun fillToken(config: PersonalizationConfig, cardData: CardData) {
config.itsToken = cardData.token_contract_address.isNotEmpty() || cardData.token_symbol.isNotEmpty()
config.cardData.token_contract_address = cardData.token_contract_address
config.cardData.token_symbol = cardData.token_symbol
config.cardData.token_decimal = cardData.token_decimal
}
private fun fillSigningMethod(config: PersonalizationConfig, signingMethod: Long) {
val mask = SigningMethodMask(signingMethod.toInt())
if (mask.contains(SigningMethod.SignHash)) config.SigningMethod0 = true
if (mask.contains(SigningMethod.SignRaw)) config.SigningMethod1 = true
if (mask.contains(SigningMethod.SignHashValidateByIssuer)) config.SigningMethod2 = true
if (mask.contains(SigningMethod.SignRawValidateByIssuer)) config.SigningMethod3 = true
if (mask.contains(SigningMethod.SignHashValidateByIssuerWriteIssuerData)) config.SigningMethod4 = true
if (mask.contains(SigningMethod.SignRawValidateByIssuerWriteIssuerData)) config.SigningMethod5 = true
}
private fun fillNdef(config: PersonalizationConfig, ndef: MutableList<NdefRecord>) {
ndef.forEach { record ->
when (record.type) {
NdefRecord.Type.URI -> config.uri = record.value
NdefRecord.Type.AAR -> config.aar = record.value
NdefRecord.Type.TEXT -> {
}
}
}
}
}
internal class ConfigToJson : Converter<PersonalizationConfig, PersonalizationJson> {
override fun convert(from: PersonalizationConfig): PersonalizationJson {
val jsonDto = PersonalizationJson()
jsonDto.apply {
releaseVersion = false
issuerName = from.issuerName
series = from.series
startNumber = from.startNumber
count = from.count
PIN = from.PIN
PIN2 = from.PIN2
PIN3 = from.PIN3
hexCrExKey = from.hexCrExKey
CVC = from.CVC
pauseBeforePIN2 = from.pauseBeforePIN2
smartSecurityDelay = from.smartSecurityDelay
curveID = from.curveID
MaxSignatures = from.MaxSignatures
isReusable = from.isReusable
allowSwapPIN = from.allowSwapPIN
allowSwapPIN2 = from.allowSwapPIN2
useActivation = from.useActivation
useCVC = from.useCVC
useNDEF = from.useNDEF
useDynamicNDEF = from.useDynamicNDEF
useOneCommandAtTime = from.useOneCommandAtTime
useBlock = from.useBlock
allowSelectBlockchain = from.allowSelectBlockchain
forbidPurgeWallet = from.forbidPurgeWallet
protocolAllowUnencrypted = from.protocolAllowUnencrypted
protocolAllowStaticEncryption = from.protocolAllowStaticEncryption
protectIssuerDataAgainstReplay = from.protectIssuerDataAgainstReplay
forbidDefaultPIN = from.forbidDefaultPIN
disablePrecomputedNDEF = from.disablePrecomputedNDEF
skipSecurityDelayIfValidatedByIssuer = from.skipSecurityDelayIfValidatedByIssuer
skipCheckPIN2andCVCIfValidatedByIssuer = from.skipCheckPIN2andCVCIfValidatedByIssuer
skipSecurityDelayIfValidatedByLinkedTerminal = from.skipSecurityDelayIfValidatedByLinkedTerminal
restrictOverwriteIssuerDataEx = from.restrictOverwriteIssuerDataEx
requireTerminalTxSignature = from.requireTerminalTxSignature
requireTerminalCertSignature = from.requireTerminalCertSignature
checkPIN3onCard = from.checkPIN3onCard
createWallet = if (from.createWallet) 1 else 0
issuerData = from.issuerData
cardData = from.cardData
// numberFormat = from.numberFormat
}
fillSigningMethod(jsonDto, from)
fillNdef(jsonDto, from)
return jsonDto
}
private fun fillSigningMethod(jsonDto: PersonalizationJson, from: PersonalizationConfig) {
jsonDto.SigningMethod = PersonalizationConfig.makeSigningMask(from).rawValue.toLong()
}
private fun fillNdef(jsonDto: PersonalizationJson, from: PersonalizationConfig) {
fun add(value: String, type: NdefRecord.Type) {
if (value.isNotEmpty()) jsonDto.ndef.add(NdefRecord(type, value))
}
if (from.aarCustom.isNotEmpty()) add(from.aarCustom, NdefRecord.Type.AAR)
else add(from.aar, NdefRecord.Type.AAR)
add(from.uri, NdefRecord.Type.URI)
}
}

View file

@ -1,7 +1,9 @@
package com.tangem.devkit.ucase.variants.personalize.dto
import com.tangem.commands.EllipticCurve
import com.tangem.commands.personalization.entities.NdefRecord
import com.tangem.commands.SigningMethod
import com.tangem.commands.SigningMethodMask
import com.tangem.commands.SigningMethodMaskBuilder
/**
[REDACTED_AUTHOR]
@ -11,11 +13,9 @@ class PersonalizationConfig {
// Card number
var series = ""
var startNumber: Long = 0
var batchId = ""
// Common
var curveID = ""
var blockchain = ""
var blockchainCustom = ""
var MaxSignatures: Long = 0
var createWallet = false
@ -38,10 +38,8 @@ class PersonalizationConfig {
// Token
var itsToken = false
var symbol = ""
var contractAddress = ""
var decimal: Long = 0
// Product mask
var cardData = CardData()
// Settings mask
@ -66,6 +64,7 @@ class PersonalizationConfig {
var protocolAllowUnencrypted = false
var protocolAllowStaticEncryption = false
// Settings mask
var useNDEF = false
var useDynamicNDEF = false
var disablePrecomputedNDEF = false
@ -80,17 +79,24 @@ class PersonalizationConfig {
var CVC = ""
var pauseBeforePIN2: Long = 0
// Fields from JSON
// var releaseVersion = true - don't use in personalization
// var count = 1050 - don't use in personalization
// var numberFormat = "" - don't use in personalization
var count: Long = 0
var issuerName = ""
var issuerData = null
companion object {
fun default(): PersonalizationConfig {
return PersonalizationConfig().apply {
// Card number
series = "BB"
startNumber = 300000000000L
batchId = "ffff"
// Common
curveID = EllipticCurve.Secp256k1.curve
blockchain = "ETH"
blockchainCustom = ""
MaxSignatures = 999999L
createWallet = true
@ -113,11 +119,8 @@ class PersonalizationConfig {
// Token
itsToken = false
symbol = ""
contractAddress = ""
decimal = 0L
cardData = CardData()
cardData = CardData.default()
// Settings mask
isReusable = true
@ -154,17 +157,67 @@ class PersonalizationConfig {
PIN3 = ""
CVC = "000"
pauseBeforePIN2 = 5000L
count = 1050
issuerName = "TANGEM"
issuerData = null
}
}
fun makeSigningMask(from: PersonalizationConfig): SigningMethodMask {
val signingMethodMaskBuilder = SigningMethodMaskBuilder()
if (from.SigningMethod0) {
signingMethodMaskBuilder.add(SigningMethod.SignHash)
}
if (from.SigningMethod1) {
signingMethodMaskBuilder.add(SigningMethod.SignRaw)
}
if (from.SigningMethod2) {
signingMethodMaskBuilder.add(SigningMethod.SignHashValidateByIssuer)
}
if (from.SigningMethod3) {
signingMethodMaskBuilder.add(SigningMethod.SignRawValidateByIssuer)
}
if (from.SigningMethod4) {
signingMethodMaskBuilder.add(SigningMethod.SignHashValidateByIssuerWriteIssuerData)
}
if (from.SigningMethod5) {
signingMethodMaskBuilder.add(SigningMethod.SignRawValidateByIssuerWriteIssuerData)
}
if (from.SigningMethod6) {
signingMethodMaskBuilder.add(SigningMethod.SignHash)
}
return signingMethodMaskBuilder.build()
}
}
}
class CardData {
var date = "2020-02-17"
var batch = "FF87"
var blockchain = "IROHA"
var product_note = true
var date = ""
var batch = ""
var blockchain = ""
var token_symbol = ""
var token_contract_address = ""
var token_decimal: Int = 0
var product_note = false
var product_tag = false
var product_id_card = false
var product_id_issuer = false
companion object {
fun default(): CardData {
return CardData().apply {
date = "2020-02-17"
batch = "FFFF"
blockchain = "ETH"
token_symbol = ""
token_contract_address = ""
token_decimal = 0
product_note = true
product_tag = false
product_id_card = false
product_id_issuer = false
}
}
}
}

View file

@ -0,0 +1,52 @@
package com.tangem.devkit.ucase.variants.personalize.dto
import com.tangem.commands.personalization.entities.NdefRecord
class PersonalizationJson {
var releaseVersion = false
var issuerName = ""
var series = ""
var startNumber = 0L
var count = 0L
var PIN = ""
var PIN2 = ""
var PIN3 = ""
var hexCrExKey = ""
var CVC = ""
var pauseBeforePIN2 = 0L
var smartSecurityDelay = false
var curveID = ""
var SigningMethod = 0L
var MaxSignatures = 0L
var isReusable = false
var allowSwapPIN = false
var allowSwapPIN2 = false
var useActivation = false
var useCVC = false
var useNDEF = false
var useDynamicNDEF = false
var useOneCommandAtTime = false
var useBlock = false
var allowSelectBlockchain = false
var forbidPurgeWallet = false
var protocolAllowUnencrypted = false
var protocolAllowStaticEncryption = false
var protectIssuerDataAgainstReplay = false
var forbidDefaultPIN = false
var disablePrecomputedNDEF = false
var skipSecurityDelayIfValidatedByIssuer = false
var skipCheckPIN2andCVCIfValidatedByIssuer = false
var skipSecurityDelayIfValidatedByLinkedTerminal = false
var restrictOverwriteIssuerDataEx = false
var requireTerminalTxSignature = false
var requireTerminalCertSignature = false
var checkPIN3onCard = false
var createWallet = 0L
var issuerData = null
var ndef = mutableListOf<NdefRecord>()
var cardData = CardData()
var numberFormat = ""
}