Updated on 2026-08-14
This commit is contained in:
parent
336ec4a1ed
commit
53599d8a3e
14 changed files with 201 additions and 191 deletions
|
|
@ -1,7 +1,6 @@
|
|||
package com.tangem.blockchain.common
|
||||
|
||||
import com.google.common.truth.Truth
|
||||
import com.tangem.Config
|
||||
import com.tangem.SessionEnvironment
|
||||
import com.tangem.blockchain.blockchains.binance.BinanceWalletManager
|
||||
import com.tangem.blockchain.blockchains.bitcoin.BitcoinWalletManager
|
||||
|
|
@ -20,7 +19,7 @@ import org.junit.Test
|
|||
|
||||
internal class WalletManagerFactoryTest {
|
||||
|
||||
private val sessionEnvironment = SessionEnvironment(null, Config(), null, null)
|
||||
private val sessionEnvironment = SessionEnvironment()
|
||||
|
||||
@Test
|
||||
fun createBitcoinWalletManager() {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem
|
||||
|
||||
import com.tangem.commands.Command
|
||||
import com.tangem.commands.CommandResponse
|
||||
import com.tangem.commands.OpenSessionCommand
|
||||
import com.tangem.commands.ReadCommand
|
||||
|
|
@ -20,8 +21,6 @@ import kotlinx.coroutines.flow.*
|
|||
*/
|
||||
interface CardSessionRunnable<T : CommandResponse> {
|
||||
|
||||
val performPreflightRead: Boolean
|
||||
|
||||
val requiresPin2: Boolean
|
||||
|
||||
/**
|
||||
|
|
@ -57,7 +56,7 @@ enum class TagType {
|
|||
* If null, a default header and text body will be used.
|
||||
*/
|
||||
class CardSession(
|
||||
val environment: SessionEnvironment,
|
||||
private val environmentService: SessionEnvironmentService,
|
||||
private val reader: CardReader,
|
||||
val viewDelegate: SessionViewDelegate,
|
||||
private var cardId: String? = null,
|
||||
|
|
@ -77,6 +76,11 @@ class CardSession(
|
|||
|
||||
private val tag = this.javaClass.simpleName
|
||||
|
||||
private var performPreflightRead = true
|
||||
private var pin2Required = false
|
||||
|
||||
val environment = environmentService.createEnvironment(cardId)
|
||||
|
||||
/**
|
||||
* This method starts a card session, performs preflight [ReadCommand],
|
||||
* invokes [CardSessionRunnable.run] and closes the session.
|
||||
|
|
@ -87,25 +91,10 @@ class CardSession(
|
|||
runnable: T, callback: (result: CompletionResult<R>) -> Unit
|
||||
) {
|
||||
|
||||
if (environment.pin1 == null) {
|
||||
viewDelegate.onSessionStarted(cardId)
|
||||
viewDelegate.onPinRequested(PinType.Pin1) {
|
||||
environment.pin1 = PinCode(it)
|
||||
startWithRunnable(runnable, callback)
|
||||
}
|
||||
return
|
||||
}
|
||||
if ((runnable as? Command<*>)?.performPreflightRead == false) performPreflightRead = false
|
||||
pin2Required = runnable.requiresPin2
|
||||
|
||||
if (runnable.requiresPin2 && environment.pin2 == null) {
|
||||
viewDelegate.onSessionStarted(cardId)
|
||||
viewDelegate.onPinRequested(PinType.Pin2) {
|
||||
environment.pin2 = PinCode(it)
|
||||
startWithRunnable(runnable, callback)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
start(runnable.performPreflightRead) { session, error ->
|
||||
start() { session, error ->
|
||||
if (error != null) {
|
||||
callback(CompletionResult.Failure(error))
|
||||
return@start
|
||||
|
|
@ -135,7 +124,6 @@ class CardSession(
|
|||
* @param callback: callback with the card session. Can contain [TangemSdkError] if something goes wrong.
|
||||
*/
|
||||
fun start(
|
||||
performPreflightRead: Boolean = true,
|
||||
callback: (session: CardSession, error: TangemSdkError?) -> Unit
|
||||
) {
|
||||
|
||||
|
|
@ -143,6 +131,26 @@ class CardSession(
|
|||
callback(this, TangemSdkError.Busy())
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
if (environment.pin1 == null) {
|
||||
viewDelegate.onSessionStarted(cardId)
|
||||
viewDelegate.onPinRequested(PinType.Pin1) {
|
||||
environment.pin1 = PinCode(it)
|
||||
start(callback)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if (pin2Required && environment.pin2 == null) {
|
||||
viewDelegate.onSessionStarted(cardId)
|
||||
viewDelegate.onPinRequested(PinType.Pin2) {
|
||||
environment.pin2 = PinCode(it)
|
||||
start(callback)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
state = CardSessionState.Active
|
||||
viewDelegate.onSessionStarted(cardId)
|
||||
|
||||
|
|
@ -196,6 +204,7 @@ class CardSession(
|
|||
return@run
|
||||
}
|
||||
environment.card = result.data
|
||||
environmentService.updateEnvironment(environment, result.data.cardId)
|
||||
cardId = receivedCardId
|
||||
callback(this, null)
|
||||
}
|
||||
|
|
@ -231,7 +240,7 @@ class CardSession(
|
|||
}
|
||||
|
||||
private fun stopSession() {
|
||||
environment.saveCardValues()
|
||||
environmentService.saveEnvironmentValues(environment, cardId)
|
||||
reader.stopSession()
|
||||
state = CardSessionState.Inactive
|
||||
scope.cancel()
|
||||
|
|
|
|||
|
|
@ -38,12 +38,16 @@ class Config(
|
|||
|
||||
var handleErrors: Boolean = true,
|
||||
|
||||
var defaultPin1: String = "000000",
|
||||
var defaultPin1: String = DEFAULT_PIN_1,
|
||||
|
||||
var defaultPin2: String = "000",
|
||||
var defaultPin2: String = DEFAULT_PIN_2,
|
||||
|
||||
var savePin1InStaticField: Boolean = true,
|
||||
|
||||
var savePin2InStaticField: Boolean = false
|
||||
|
||||
)
|
||||
) {
|
||||
companion object {
|
||||
const val DEFAULT_PIN_1 = "000000"
|
||||
const val DEFAULT_PIN_2 = "000"
|
||||
}
|
||||
}
|
||||
|
|
@ -2,9 +2,7 @@ package com.tangem
|
|||
|
||||
import com.tangem.commands.Card
|
||||
import com.tangem.commands.EllipticCurve
|
||||
import com.tangem.common.CardValuesStorage
|
||||
import com.tangem.common.PinCode
|
||||
import com.tangem.common.TerminalKeysService
|
||||
import com.tangem.crypto.CryptoUtils.generatePublicKey
|
||||
|
||||
|
||||
|
|
@ -27,79 +25,23 @@ import com.tangem.crypto.CryptoUtils.generatePublicKey
|
|||
*
|
||||
*/
|
||||
class SessionEnvironment(
|
||||
cardId: String?,
|
||||
private val config: Config,
|
||||
terminalKeysService: TerminalKeysService?,
|
||||
private val cardValuesStorage: CardValuesStorage?
|
||||
) {
|
||||
var pin1: PinCode? = PinCode(Config.DEFAULT_PIN_1, true),
|
||||
var pin2: PinCode? = PinCode(Config.DEFAULT_PIN_2, true),
|
||||
var cvc: ByteArray? = null,
|
||||
|
||||
var pin1: PinCode?
|
||||
var pin2: PinCode?
|
||||
var cvc: ByteArray? = null
|
||||
var terminalKeys: KeyPair? = null,
|
||||
var cardFilter: CardFilter = CardFilter(),
|
||||
val handleErrors: Boolean = true,
|
||||
|
||||
var terminalKeys: KeyPair? = null
|
||||
var cardFilter: CardFilter
|
||||
val handleErrors: Boolean
|
||||
var encryptionMode: EncryptionMode = EncryptionMode.NONE,
|
||||
var encryptionKey: ByteArray? = null,
|
||||
|
||||
var encryptionMode: EncryptionMode
|
||||
var encryptionKey: ByteArray? = null
|
||||
var cardVerification: VerificationState = VerificationState.NotVerified,
|
||||
var cardValidation: VerificationState = VerificationState.NotVerified,
|
||||
var codeVerification: VerificationState = VerificationState.NotVerified,
|
||||
|
||||
var cardVerification: VerificationState
|
||||
var cardValidation: VerificationState
|
||||
var codeVerification: VerificationState
|
||||
|
||||
var card: Card? = null
|
||||
|
||||
init {
|
||||
terminalKeys = if (config.linkedTerminal) terminalKeysService?.getKeys() else null
|
||||
cardFilter = config.cardFilter
|
||||
handleErrors = config.handleErrors
|
||||
|
||||
encryptionMode = config.encryptionMode
|
||||
|
||||
val cardValues = cardId?.let { cardValuesStorage?.getValues(cardId) }
|
||||
|
||||
cardVerification = cardValues?.cardVerification ?: VerificationState.NotVerified
|
||||
cardValidation = cardValues?.cardValidation ?: VerificationState.NotVerified
|
||||
codeVerification = cardValues?.codeVerification ?: VerificationState.NotVerified
|
||||
|
||||
pin1 = TangemSdk.pin1
|
||||
?: if (cardValues?.isPin1Default != false) {
|
||||
PinCode(config.defaultPin1, true)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
pin2 = cardId?.let { TangemSdk.pin2[it] }
|
||||
?: if (cardValues?.isPin2Default != false) {
|
||||
PinCode(config.defaultPin2, true)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
fun restoreCardValues() {
|
||||
val cardValues = this.card?.cardId?.let { cardValuesStorage?.getValues(it) }
|
||||
cardVerification = cardValues?.cardVerification ?: VerificationState.NotVerified
|
||||
cardValidation = cardValues?.cardValidation ?: VerificationState.NotVerified
|
||||
codeVerification = cardValues?.codeVerification ?: VerificationState.NotVerified
|
||||
|
||||
if (cardValues?.isPin1Default == false && pin1?.isDefault == true) pin1 = null
|
||||
if (cardValues?.isPin2Default == false && pin1?.isDefault == true) pin2 = null
|
||||
}
|
||||
|
||||
fun saveCardValues() {
|
||||
if (config.savePin1InStaticField) {
|
||||
TangemSdk.pin1 = pin1
|
||||
}
|
||||
if (config.savePin2InStaticField) {
|
||||
card?.cardId?.let { cardId -> TangemSdk.pin2[cardId] = pin2 }
|
||||
}
|
||||
|
||||
cardValuesStorage?.saveValues(this)
|
||||
}
|
||||
|
||||
}
|
||||
var card: Card? = null
|
||||
)
|
||||
|
||||
/**
|
||||
* All possible encryption modes.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,77 @@
|
|||
package com.tangem
|
||||
|
||||
import com.tangem.common.CardValuesStorage
|
||||
import com.tangem.common.PinCode
|
||||
import com.tangem.common.TerminalKeysService
|
||||
|
||||
class SessionEnvironmentService(
|
||||
private val config: Config,
|
||||
private val terminalKeysService: TerminalKeysService?,
|
||||
private val cardValuesStorage: CardValuesStorage?
|
||||
) {
|
||||
|
||||
fun createEnvironment(cardId: String?): SessionEnvironment {
|
||||
val terminalKeys = if (config.linkedTerminal) terminalKeysService?.getKeys() else null
|
||||
|
||||
val cardValues = cardId?.let { cardValuesStorage?.getValues(cardId) }
|
||||
|
||||
val cardVerification = cardValues?.cardVerification ?: VerificationState.NotVerified
|
||||
val cardValidation = cardValues?.cardValidation ?: VerificationState.NotVerified
|
||||
val codeVerification = cardValues?.codeVerification ?: VerificationState.NotVerified
|
||||
|
||||
val pin1 = TangemSdk.pin1
|
||||
?: if (cardValues?.isPin1Default != false) {
|
||||
PinCode(config.defaultPin1, true)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
val pin2 = cardId?.let { TangemSdk.pin2[it] }
|
||||
?: if (cardValues?.isPin2Default != false) {
|
||||
PinCode(config.defaultPin2, true)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
return SessionEnvironment(
|
||||
terminalKeys = terminalKeys,
|
||||
cardFilter = config.cardFilter,
|
||||
handleErrors = config.handleErrors,
|
||||
|
||||
encryptionMode = config.encryptionMode,
|
||||
|
||||
cardVerification = cardVerification,
|
||||
cardValidation = cardValidation,
|
||||
codeVerification = codeVerification,
|
||||
|
||||
pin1 = pin1,
|
||||
pin2 = pin2
|
||||
)
|
||||
}
|
||||
|
||||
fun updateEnvironment(environment: SessionEnvironment, cardId: String) {
|
||||
val cardValues = cardId.let { cardValuesStorage?.getValues(it) }
|
||||
environment.cardVerification = cardValues?.cardVerification ?: VerificationState.NotVerified
|
||||
environment.cardValidation = cardValues?.cardValidation ?: VerificationState.NotVerified
|
||||
environment.codeVerification = cardValues?.codeVerification ?: VerificationState.NotVerified
|
||||
|
||||
if (cardValues?.isPin1Default == false && environment.pin1?.isDefault == true) environment.pin1 = null
|
||||
if (cardValues?.isPin2Default == false && environment.pin1?.isDefault == true) environment.pin2 = null
|
||||
}
|
||||
|
||||
fun saveEnvironmentValues(environment: SessionEnvironment, cardId: String?) {
|
||||
if (config.savePin1InStaticField) {
|
||||
TangemSdk.pin1 = environment.pin1
|
||||
}
|
||||
if (config.savePin2InStaticField) {
|
||||
cardId?.let { cardId -> TangemSdk.pin2[cardId] = environment.pin2 }
|
||||
}
|
||||
cardId?.let { cardId ->
|
||||
cardValuesStorage?.saveValues(cardId,
|
||||
environment.pin1?.isDefault ?: false,
|
||||
environment.pin2?.isDefault ?: false,
|
||||
environment.cardVerification, environment.cardVerification,
|
||||
environment.codeVerification)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
package com.tangem
|
||||
|
||||
import com.squareup.sqldelight.db.SqlDriver
|
||||
import com.tangem.commands.*
|
||||
import com.tangem.commands.personalization.DepersonalizeCommand
|
||||
import com.tangem.commands.personalization.DepersonalizeResponse
|
||||
|
|
@ -11,7 +10,7 @@ import com.tangem.commands.personalization.entities.Issuer
|
|||
import com.tangem.commands.personalization.entities.Manufacturer
|
||||
import com.tangem.commands.verifycard.VerifyCardCommand
|
||||
import com.tangem.commands.verifycard.VerifyCardResponse
|
||||
import com.tangem.common.CardValuesDbStorage
|
||||
import com.tangem.common.CardValuesStorage
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.common.PinCode
|
||||
import com.tangem.common.TerminalKeysService
|
||||
|
|
@ -31,15 +30,19 @@ import com.tangem.tasks.ScanTask
|
|||
* Its default implementation, DefaultCardSessionViewDelegate, is in our tangem-sdk module.
|
||||
* @property config allows to change a number of parameters for communication with Tangem cards.
|
||||
* Do not change the default values unless you know what you are doing.
|
||||
* @property terminalKeysService allows to retrieve saved terminal keys.
|
||||
*/
|
||||
class TangemSdk(
|
||||
private val reader: CardReader,
|
||||
private val viewDelegate: SessionViewDelegate,
|
||||
var config: Config = Config(),
|
||||
private val sqlDriver: SqlDriver
|
||||
cardValuesStorage: CardValuesStorage,
|
||||
terminalKeysService: TerminalKeysService? = null
|
||||
) {
|
||||
|
||||
private var terminalKeysService: TerminalKeysService? = null
|
||||
private val environmentService = SessionEnvironmentService(
|
||||
config, terminalKeysService, cardValuesStorage
|
||||
)
|
||||
|
||||
init {
|
||||
CryptoUtils.initCrypto()
|
||||
|
|
@ -369,8 +372,8 @@ class TangemSdk(
|
|||
|
||||
fun changePin1(cardId: String? = null,
|
||||
pin: ByteArray? = null,
|
||||
initialMessage: Message? = null,
|
||||
callback: (result: CompletionResult<SetPinResponse>) -> Unit) {
|
||||
initialMessage: Message? = null,
|
||||
callback: (result: CompletionResult<SetPinResponse>) -> Unit) {
|
||||
val command = ChangePinTask(PinType.Pin1, pin)
|
||||
startSessionWithRunnable(command, cardId, initialMessage, callback)
|
||||
}
|
||||
|
|
@ -408,7 +411,7 @@ class TangemSdk(
|
|||
fun <T : CommandResponse> startSessionWithRunnable(
|
||||
runnable: CardSessionRunnable<T>, cardId: String? = null, initialMessage: Message? = null,
|
||||
callback: (result: CompletionResult<T>) -> Unit) {
|
||||
val cardSession = CardSession(buildEnvironment(cardId), reader, viewDelegate, cardId, initialMessage)
|
||||
val cardSession = CardSession(environmentService, reader, viewDelegate, cardId, initialMessage)
|
||||
Thread().run { cardSession.startWithRunnable(runnable, callback) }
|
||||
}
|
||||
|
||||
|
|
@ -426,24 +429,10 @@ class TangemSdk(
|
|||
*/
|
||||
fun startSession(cardId: String? = null, initialMessage: Message? = null,
|
||||
callback: (session: CardSession, error: TangemSdkError?) -> Unit) {
|
||||
val cardSession = CardSession(buildEnvironment(cardId), reader, viewDelegate, cardId, initialMessage)
|
||||
val cardSession = CardSession(environmentService, reader, viewDelegate, cardId, initialMessage)
|
||||
Thread().run { cardSession.start(callback = callback) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows to set a particular [TerminalKeysService] to retrieve terminal keys.
|
||||
* Default implementation is provided in tangem-sdk module: [TerminalKeysStorage].
|
||||
*/
|
||||
fun setTerminalKeysService(terminalKeysService: TerminalKeysService) {
|
||||
this.terminalKeysService = terminalKeysService
|
||||
}
|
||||
|
||||
private fun buildEnvironment(cardId: String?): SessionEnvironment {
|
||||
return SessionEnvironment(
|
||||
cardId, config, terminalKeysService, CardValuesDbStorage(sqlDriver)
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
var pin1: PinCode? = null
|
||||
val pin2: MutableMap<String, PinCode?> = mutableMapOf()
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ interface CommandResponse
|
|||
*/
|
||||
abstract class Command<T : CommandResponse> : ApduSerializable<T>, CardSessionRunnable<T> {
|
||||
|
||||
override val performPreflightRead: Boolean = true
|
||||
open val performPreflightRead: Boolean = true
|
||||
override val requiresPin2: Boolean = false
|
||||
|
||||
override fun run(session: CardSession, callback: (result: CompletionResult<T>) -> Unit) {
|
||||
|
|
@ -74,10 +74,12 @@ abstract class Command<T : CommandResponse> : ApduSerializable<T>, CardSessionRu
|
|||
if (session.environment.handleErrors) {
|
||||
val error = mapError(session.environment.card, result.error)
|
||||
if (error is TangemSdkError.Pin1Required) {
|
||||
session.environment.pin1 = null
|
||||
handlePin1(session, callback)
|
||||
return@transceiveApdu
|
||||
}
|
||||
if (error is TangemSdkError.Pin2OrCvcRequired) {
|
||||
session.environment.pin2 = null
|
||||
handlePin2(session, callback)
|
||||
return@transceiveApdu
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,18 +19,6 @@ class DepersonalizeCommand : Command<DepersonalizeResponse>() {
|
|||
|
||||
override val performPreflightRead = false
|
||||
|
||||
// override fun performPreCheck(session: CardSession, callback: (result: CompletionResult<DepersonalizeResponse>) -> Unit): Boolean {
|
||||
// if (session.environment.card?.status == CardStatus.NotPersonalized) {
|
||||
// callback(CompletionResult.Failure(TangemSdkError.NotPersonalized()))
|
||||
// return true
|
||||
// }
|
||||
// if (session.environment.card?.firmwareVersion?.contains("SDK") == false) {
|
||||
// callback(CompletionResult.Failure(TangemSdkError.CannotBeDepersonalized()))
|
||||
// return true
|
||||
// }
|
||||
// return false
|
||||
// }
|
||||
|
||||
override fun serialize(environment: SessionEnvironment): CommandApdu {
|
||||
return CommandApdu(
|
||||
Instruction.Depersonalize, byteArrayOf()
|
||||
|
|
|
|||
|
|
@ -2,16 +2,21 @@ package com.tangem.common
|
|||
|
||||
import com.squareup.sqldelight.EnumColumnAdapter
|
||||
import com.squareup.sqldelight.db.SqlDriver
|
||||
import com.squareup.sqldelight.sqlite.driver.JdbcSqliteDriver
|
||||
import com.tangem.CardValues
|
||||
import com.tangem.CardValuesEntityQueries
|
||||
import com.tangem.Database
|
||||
import com.tangem.SessionEnvironment
|
||||
import com.tangem.VerificationState
|
||||
|
||||
interface CardValuesStorage {
|
||||
|
||||
fun saveValues(environment: SessionEnvironment)
|
||||
fun saveValues(cardId: String,
|
||||
isPin1Default: Boolean, isPin2Default: Boolean,
|
||||
cardVerification: VerificationState?,
|
||||
cardValidation: VerificationState?,
|
||||
codeVerification: VerificationState?)
|
||||
|
||||
fun getValues(cardId: String) : CardValues?
|
||||
fun getValues(cardId: String): CardValues?
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -28,19 +33,24 @@ class CardValuesDbStorage(driver: SqlDriver) : CardValuesStorage {
|
|||
cardValuesQueries = database.cardValuesEntityQueries
|
||||
}
|
||||
|
||||
override fun saveValues(environment: SessionEnvironment) {
|
||||
environment.card?.cardId?.let {cardId ->
|
||||
cardValuesQueries.insertOrReplace(
|
||||
cardId,
|
||||
environment.pin1?.isDefault ?: false,
|
||||
environment.pin2?.isDefault ?: false,
|
||||
environment.cardVerification, environment.cardVerification,
|
||||
environment.codeVerification
|
||||
)
|
||||
}
|
||||
override fun saveValues(cardId: String,
|
||||
isPin1Default: Boolean, isPin2Default: Boolean,
|
||||
cardVerification: VerificationState?,
|
||||
cardValidation: VerificationState?,
|
||||
codeVerification: VerificationState?) {
|
||||
cardValuesQueries.insertOrReplace(
|
||||
cardId,
|
||||
isPin1Default, isPin2Default,
|
||||
cardVerification, cardValidation, codeVerification
|
||||
)
|
||||
}
|
||||
|
||||
override fun getValues(cardId: String): CardValues? =
|
||||
override fun getValues(cardId: String): CardValues? =
|
||||
cardValuesQueries.selectByCardId(cardId).executeAsOneOrNull()
|
||||
|
||||
companion object {
|
||||
fun initJvm() = CardValuesDbStorage(
|
||||
JdbcSqliteDriver(JdbcSqliteDriver.IN_MEMORY).also { Database.Schema.create(it) }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -24,7 +24,6 @@ class ChangePinTask(
|
|||
private val pinType: PinType,
|
||||
private val pin: ByteArray? = null
|
||||
) : CardSessionRunnable<SetPinResponse> {
|
||||
override val performPreflightRead = true
|
||||
override val requiresPin2 = false
|
||||
|
||||
override fun run(session: CardSession, callback: (result: CompletionResult<SetPinResponse>) -> Unit) {
|
||||
|
|
@ -67,7 +66,10 @@ class ChangePinTask(
|
|||
val command = SetPinCommand(pin1, pin2, pin3)
|
||||
command.run(session) { result ->
|
||||
when (result) {
|
||||
is CompletionResult.Success -> savePin(pin, session.environment)
|
||||
is CompletionResult.Success -> {
|
||||
savePin(pin, session.environment)
|
||||
callback(result)
|
||||
}
|
||||
is CompletionResult.Failure -> callback(result)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import com.tangem.common.CompletionResult
|
|||
|
||||
class CreateWalletTask : CardSessionRunnable<CreateWalletResponse> {
|
||||
|
||||
override val performPreflightRead = true
|
||||
override val requiresPin2 = false
|
||||
|
||||
override fun run(session: CardSession, callback: (result: CompletionResult<CreateWalletResponse>) -> Unit) {
|
||||
|
|
|
|||
|
|
@ -15,41 +15,32 @@ import com.tangem.common.CompletionResult
|
|||
*/
|
||||
internal class ScanTask : CardSessionRunnable<Card> {
|
||||
|
||||
override val performPreflightRead = false
|
||||
override val requiresPin2 = false
|
||||
|
||||
override fun run(session: CardSession, callback: (result: CompletionResult<Card>) -> Unit) {
|
||||
|
||||
|
||||
if (session.connectedTag == TagType.Slix) {
|
||||
readSlixTag(session, callback)
|
||||
return
|
||||
}
|
||||
|
||||
ReadCommand().run(session) { readResult ->
|
||||
when(readResult) {
|
||||
is CompletionResult.Failure -> callback(readResult)
|
||||
is CompletionResult.Success -> {
|
||||
val card = readResult.data
|
||||
session.environment.card = card
|
||||
session.environment.restoreCardValues()
|
||||
if (session.environment.pin1 != null && session.environment.pin2 != null) {
|
||||
val checkPinCommand = SetPinCommand(session.environment.pin1!!.value, session.environment.pin2!!.value)
|
||||
checkPinCommand.run(session) { result ->
|
||||
when (result) {
|
||||
is CompletionResult.Failure -> {
|
||||
session.environment.pin2 = null
|
||||
}
|
||||
}
|
||||
runCheckWalletIfNeeded(card, session, callback)
|
||||
}
|
||||
} else {
|
||||
runCheckWalletIfNeeded(card, session, callback)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
val card = session.environment.card
|
||||
if (card == null) {
|
||||
callback(CompletionResult.Failure(TangemSdkError.CardError()))
|
||||
return
|
||||
}
|
||||
if (session.environment.pin1 != null && session.environment.pin2 != null) {
|
||||
val checkPinCommand = SetPinCommand(session.environment.pin1!!.value, session.environment.pin2!!.value)
|
||||
checkPinCommand.run(session) { result ->
|
||||
when (result) {
|
||||
is CompletionResult.Failure -> {
|
||||
session.environment.pin2 = null
|
||||
}
|
||||
}
|
||||
runCheckWalletIfNeeded(card, session, callback)
|
||||
}
|
||||
} else {
|
||||
runCheckWalletIfNeeded(card, session, callback)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun runCheckWalletIfNeeded(
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package com.tangem.common.apdu
|
||||
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import com.tangem.Config
|
||||
import com.tangem.SessionEnvironment
|
||||
import com.tangem.common.tlv.TlvBuilder
|
||||
import com.tangem.common.tlv.TlvTag
|
||||
|
|
@ -10,7 +9,7 @@ import org.junit.Test
|
|||
|
||||
class CommandApduTest {
|
||||
|
||||
val sessionEnvironment = SessionEnvironment(null, Config(), null, null)
|
||||
private val sessionEnvironment = SessionEnvironment()
|
||||
|
||||
@Test
|
||||
fun `simple READ command to bytes`() {
|
||||
|
|
@ -26,7 +25,7 @@ class CommandApduTest {
|
|||
|
||||
assertThat(commandApdu.apduData)
|
||||
.isEqualTo(expected)
|
||||
assertThat(listOf(1, 2)).containsExactlyElementsIn(listOf(1,2))
|
||||
assertThat(listOf(1, 2)).containsExactlyElementsIn(listOf(1, 2))
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import com.tangem.Config
|
|||
import com.tangem.Database
|
||||
import com.tangem.SessionViewDelegate
|
||||
import com.tangem.TangemSdk
|
||||
import com.tangem.common.CardValuesDbStorage
|
||||
import com.tangem.tangem_sdk_new.DefaultSessionViewDelegate
|
||||
import com.tangem.tangem_sdk_new.NfcLifecycleObserver
|
||||
import com.tangem.tangem_sdk_new.TerminalKeysStorage
|
||||
|
|
@ -18,10 +19,10 @@ fun TangemSdk.Companion.init(activity: FragmentActivity, config: Config = Config
|
|||
viewDelegate.activity = activity
|
||||
|
||||
val databaseDriver = AndroidSqliteDriver(Database.Schema, activity.applicationContext, "cards.db")
|
||||
val tangemSdk = TangemSdk(nfcManager.reader, viewDelegate, config, databaseDriver)
|
||||
tangemSdk.setTerminalKeysService(TerminalKeysStorage(activity.application))
|
||||
|
||||
return tangemSdk
|
||||
return TangemSdk(
|
||||
nfcManager.reader, viewDelegate, config,
|
||||
CardValuesDbStorage(databaseDriver), TerminalKeysStorage(activity.application)
|
||||
)
|
||||
}
|
||||
|
||||
fun TangemSdk.Companion.customInit(
|
||||
|
|
@ -30,17 +31,15 @@ fun TangemSdk.Companion.customInit(
|
|||
config: Config = Config()
|
||||
): TangemSdk {
|
||||
val nfcManager = TangemSdk.initNfcManager(activity)
|
||||
val databaseDriver = AndroidSqliteDriver(Database.Schema, activity.applicationContext, "cards.db")
|
||||
|
||||
val tangemSdk = TangemSdk(
|
||||
return TangemSdk(
|
||||
nfcManager.reader,
|
||||
viewDelegate ?: DefaultSessionViewDelegate(nfcManager.reader)
|
||||
.apply { this.activity = activity },
|
||||
config,
|
||||
AndroidSqliteDriver(Database.Schema, activity.applicationContext, "cards.db")
|
||||
CardValuesDbStorage(databaseDriver), TerminalKeysStorage(activity.application)
|
||||
)
|
||||
tangemSdk.setTerminalKeysService(TerminalKeysStorage(activity.application))
|
||||
|
||||
return tangemSdk
|
||||
}
|
||||
|
||||
fun TangemSdk.Companion.initNfcManager(activity: FragmentActivity): NfcManager {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue