Updated on 2026-08-14
This commit is contained in:
parent
8b75e37e30
commit
a9bca131c3
386 changed files with 1369 additions and 1347 deletions
|
|
@ -19,10 +19,10 @@ import com.tangem.datasource.local.visa.VisaOtpData
|
|||
import com.tangem.datasource.local.visa.hasSavedOTP
|
||||
import com.tangem.domain.card.common.visa.VisaWalletPublicKeyUtility
|
||||
import com.tangem.domain.models.scan.CardDTO
|
||||
import com.tangem.domain.visa.datasource.VisaAuthRemoteDataSource
|
||||
import com.tangem.domain.visa.error.VisaActivationError
|
||||
import com.tangem.domain.visa.model.*
|
||||
import com.tangem.domain.visa.repository.VisaActivationRepository
|
||||
import com.tangem.domain.visa.datasource.VisaAuthRemoteDataSource
|
||||
import com.tangem.operations.GenerateOTPCommand
|
||||
import com.tangem.operations.attestation.AttestCardKeyCommand
|
||||
import com.tangem.operations.pins.SetUserCodeCommand
|
||||
|
|
@ -31,11 +31,11 @@ import com.tangem.operations.sign.SignHashResponse
|
|||
import com.tangem.operations.wallet.CreateWalletTask
|
||||
import com.tangem.sdk.api.visa.VisaCardActivationResponse
|
||||
import com.tangem.sdk.api.visa.VisaCardActivationTaskMode
|
||||
import com.tangem.utils.logging.TangemLogger
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import kotlinx.coroutines.*
|
||||
import timber.log.Timber
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.time.measureTimedValue
|
||||
|
||||
|
|
@ -94,7 +94,7 @@ class VisaCardActivationTask @AssistedInject constructor(
|
|||
}
|
||||
}
|
||||
}
|
||||
Timber.i("VisaCardActivationTask all time: ${timedResult.duration}")
|
||||
TangemLogger.i("VisaCardActivationTask all time: ${timedResult.duration}")
|
||||
return timedResult.value
|
||||
}
|
||||
|
||||
|
|
@ -109,11 +109,11 @@ class VisaCardActivationTask @AssistedInject constructor(
|
|||
}
|
||||
}
|
||||
}
|
||||
Timber.i("AttestCardKeyCommand time: ${timedResult.duration}")
|
||||
TangemLogger.i("AttestCardKeyCommand time: ${timedResult.duration}")
|
||||
|
||||
return when (val result = timedResult.value) {
|
||||
is CompletionResult.Success -> {
|
||||
Timber.i("AttestCardKeyCommand success")
|
||||
TangemLogger.i("AttestCardKeyCommand success")
|
||||
processSignedAuthorizationChallenge(
|
||||
signedChallenge = challengeToSign.toSignedChallenge(
|
||||
signedChallenge = result.data.cardSignature.toHexString(),
|
||||
|
|
@ -122,7 +122,7 @@ class VisaCardActivationTask @AssistedInject constructor(
|
|||
)
|
||||
}
|
||||
is CompletionResult.Failure -> {
|
||||
Timber.e("AttestCardKeyCommand failure ${result.error}")
|
||||
TangemLogger.e("AttestCardKeyCommand failure ${result.error}")
|
||||
CompletionResult.Failure(result.error)
|
||||
}
|
||||
}
|
||||
|
|
@ -206,15 +206,15 @@ class VisaCardActivationTask @AssistedInject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
Timber.i("CreateWalletTask time: ${timedResult.duration}")
|
||||
TangemLogger.i("CreateWalletTask time: ${timedResult.duration}")
|
||||
|
||||
when (val result = timedResult.value) {
|
||||
is CompletionResult.Success -> {
|
||||
Timber.i("CreateWalletTask success")
|
||||
TangemLogger.i("CreateWalletTask success")
|
||||
CompletionResult.Success(Unit)
|
||||
}
|
||||
is CompletionResult.Failure -> {
|
||||
Timber.e("CreateWalletTask failure ${result.error}")
|
||||
TangemLogger.e("CreateWalletTask failure ${result.error}")
|
||||
CompletionResult.Failure(result.error)
|
||||
}
|
||||
}
|
||||
|
|
@ -237,11 +237,11 @@ class VisaCardActivationTask @AssistedInject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
Timber.i("GenerateOTPCommand time: ${timedResult.duration}")
|
||||
TangemLogger.i("GenerateOTPCommand time: ${timedResult.duration}")
|
||||
|
||||
return when (val result = timedResult.value) {
|
||||
is CompletionResult.Success -> {
|
||||
Timber.i("GenerateOTPCommand success")
|
||||
TangemLogger.i("GenerateOTPCommand success")
|
||||
otpStorage.saveOTP(
|
||||
cardId = cardId,
|
||||
data = VisaOtpData(result.data.rootOTP, result.data.rootOTPCounter),
|
||||
|
|
@ -249,7 +249,7 @@ class VisaCardActivationTask @AssistedInject constructor(
|
|||
CompletionResult.Success(Unit)
|
||||
}
|
||||
is CompletionResult.Failure -> {
|
||||
Timber.e("GenerateOTPCommand failure ${result.error}")
|
||||
TangemLogger.e("GenerateOTPCommand failure ${result.error}")
|
||||
CompletionResult.Failure(result.error)
|
||||
}
|
||||
}
|
||||
|
|
@ -278,11 +278,11 @@ class VisaCardActivationTask @AssistedInject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
Timber.i("SignHashCommand time: ${timedResult.duration}")
|
||||
TangemLogger.i("SignHashCommand time: ${timedResult.duration}")
|
||||
|
||||
return when (val result = timedResult.value) {
|
||||
is CompletionResult.Success -> {
|
||||
Timber.i("SignHashCommand success")
|
||||
TangemLogger.i("SignHashCommand success")
|
||||
handleSignedData(
|
||||
dataToSign = dataToSign,
|
||||
response = result.data,
|
||||
|
|
@ -290,7 +290,7 @@ class VisaCardActivationTask @AssistedInject constructor(
|
|||
)
|
||||
}
|
||||
is CompletionResult.Failure -> {
|
||||
Timber.e("SignHashCommand failure ${result.error}")
|
||||
TangemLogger.e("SignHashCommand failure ${result.error}")
|
||||
CompletionResult.Failure(result.error)
|
||||
}
|
||||
}
|
||||
|
|
@ -336,7 +336,7 @@ class VisaCardActivationTask @AssistedInject constructor(
|
|||
return CompletionResult.Success(Unit)
|
||||
}
|
||||
|
||||
Timber.i("Setting access code")
|
||||
TangemLogger.i("Setting access code")
|
||||
|
||||
val task = SetUserCodeCommand.changeAccessCode(mode.accessCode)
|
||||
|
||||
|
|
@ -348,15 +348,15 @@ class VisaCardActivationTask @AssistedInject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
Timber.i("SetUserCodeCommand time: ${timedResult.duration}")
|
||||
TangemLogger.i("SetUserCodeCommand time: ${timedResult.duration}")
|
||||
|
||||
return when (val result = timedResult.value) {
|
||||
is CompletionResult.Success -> {
|
||||
Timber.i("SetUserCodeCommand success")
|
||||
TangemLogger.i("SetUserCodeCommand success")
|
||||
CompletionResult.Success(Unit)
|
||||
}
|
||||
is CompletionResult.Failure -> {
|
||||
Timber.i("SetUserCodeCommand failure ${result.error}")
|
||||
TangemLogger.i("SetUserCodeCommand failure ${result.error}")
|
||||
CompletionResult.Failure(result.error)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,9 +14,9 @@ import com.tangem.tap.domain.userWalletList.model.UserWalletEncryptionKey
|
|||
import com.tangem.tap.domain.userWalletList.model.UserWalletSensitiveInformation
|
||||
import com.tangem.tap.domain.userWalletList.repository.UserWalletsSensitiveInformationRepository
|
||||
import com.tangem.tap.domain.userWalletList.utils.sensitiveInformation
|
||||
import com.tangem.utils.logging.TangemLogger
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import timber.log.Timber
|
||||
import javax.crypto.spec.SecretKeySpec
|
||||
|
||||
internal class DefaultUserWalletsSensitiveInformationRepository(
|
||||
|
|
@ -123,7 +123,7 @@ internal class DefaultUserWalletsSensitiveInformationRepository(
|
|||
this@decodeToSensitiveInformation.decodeToString(throwOnInvalidSequence = true),
|
||||
)
|
||||
} catch (e: CharacterCodingException) {
|
||||
Timber.e(e, "Unable to decode sensitive information")
|
||||
TangemLogger.e("Unable to decode sensitive information", e)
|
||||
|
||||
null
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,19 +10,18 @@ import com.tangem.common.extensions.toHexString
|
|||
import com.tangem.core.error.ext.tangemError
|
||||
import com.tangem.datasource.local.visa.VisaAuthTokenStorage
|
||||
import com.tangem.domain.card.common.visa.VisaWalletPublicKeyUtility
|
||||
import com.tangem.domain.visa.model.VisaCardActivationStatus
|
||||
import com.tangem.domain.visa.datasource.VisaAuthRemoteDataSource
|
||||
import com.tangem.domain.visa.error.VisaActivationError
|
||||
import com.tangem.domain.visa.error.VisaApiError
|
||||
import com.tangem.domain.visa.error.VisaCardScanError
|
||||
import com.tangem.domain.visa.model.*
|
||||
import com.tangem.domain.visa.repository.VisaActivationRepository
|
||||
import com.tangem.domain.visa.datasource.VisaAuthRemoteDataSource
|
||||
import com.tangem.operations.attestation.AttestCardKeyCommand
|
||||
import com.tangem.operations.attestation.AttestCardKeyResponse
|
||||
import com.tangem.operations.attestation.AttestWalletKeyResponse
|
||||
import com.tangem.operations.attestation.AttestWalletKeyTask
|
||||
import com.tangem.utils.logging.TangemLogger
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
import kotlin.coroutines.resume
|
||||
|
||||
|
|
@ -38,10 +37,10 @@ internal class VisaCardScanHandler @Inject constructor(
|
|||
)
|
||||
|
||||
suspend fun handleVisaCardScan(session: CardSession): CompletionResult<VisaCardActivationStatus> {
|
||||
Timber.i("Attempting to handle Visa card scan")
|
||||
TangemLogger.i("Attempting to handle Visa card scan")
|
||||
|
||||
val card = session.environment.card ?: run {
|
||||
Timber.e("Card is null")
|
||||
TangemLogger.e("Card is null")
|
||||
return CompletionResult.Failure(TangemSdkError.MissingPreflightRead())
|
||||
}
|
||||
|
||||
|
|
@ -68,12 +67,12 @@ internal class VisaCardScanHandler @Inject constructor(
|
|||
}
|
||||
|
||||
private suspend fun SessionContext.handleWalletAuthorization(): CompletionResult<VisaCardActivationStatus> {
|
||||
Timber.i("Started handling authorization using Visa wallet")
|
||||
TangemLogger.i("Started handling authorization using Visa wallet")
|
||||
|
||||
val card = session.environment.card ?: return CompletionResult.Failure(TangemSdkError.MissingPreflightRead())
|
||||
|
||||
val wallet = card.wallets.firstOrNull { it.curve == EllipticCurve.Secp256k1 } ?: run {
|
||||
Timber.e("Failed to find extended public key while handling wallet authorization")
|
||||
TangemLogger.e("Failed to find extended public key while handling wallet authorization")
|
||||
return CompletionResult.Failure(VisaCardScanError.FailedToFindWallet.tangemError)
|
||||
}
|
||||
|
||||
|
|
@ -82,14 +81,14 @@ internal class VisaCardScanHandler @Inject constructor(
|
|||
return CompletionResult.Failure(it.tangemError)
|
||||
}
|
||||
|
||||
Timber.i("Requesting challenge for wallet authorization")
|
||||
TangemLogger.i("Requesting challenge for wallet authorization")
|
||||
|
||||
val challengeResponse = visaAuthRemoteDataSource.getCardWalletAuthChallenge(
|
||||
cardId = card.cardId,
|
||||
// This is the wallet public key, not the address and it's alright, as the API expects it in this format
|
||||
cardWalletAddress = wallet.publicKey.toHexString(),
|
||||
).getOrElse { error ->
|
||||
Timber.i("Failed to get Access token for Wallet public key authorization")
|
||||
TangemLogger.i("Failed to get Access token for Wallet public key authorization")
|
||||
return CompletionResult.Failure(error.tangemError)
|
||||
}
|
||||
|
||||
|
|
@ -103,7 +102,7 @@ internal class VisaCardScanHandler @Inject constructor(
|
|||
val signature = signChallengeResult.data.walletSignature
|
||||
val salt = signChallengeResult.data.salt
|
||||
|
||||
Timber.i("Challenge signed with Wallet public key")
|
||||
TangemLogger.i("Challenge signed with Wallet public key")
|
||||
handleWalletAuthorizationTokens(
|
||||
cardWalletAddress = walletAddress.value,
|
||||
signedChallenge = challengeResponse.toSignedChallenge(
|
||||
|
|
@ -113,7 +112,9 @@ internal class VisaCardScanHandler @Inject constructor(
|
|||
)
|
||||
}
|
||||
is CompletionResult.Failure -> {
|
||||
Timber.e("Error during Wallet authorization process. Tangem Sdk Error: ${signChallengeResult.error}")
|
||||
TangemLogger.e(
|
||||
"Error during Wallet authorization process. Tangem Sdk Error: ${signChallengeResult.error}",
|
||||
)
|
||||
CompletionResult.Failure(signChallengeResult.error)
|
||||
}
|
||||
}
|
||||
|
|
@ -125,19 +126,19 @@ internal class VisaCardScanHandler @Inject constructor(
|
|||
): CompletionResult<VisaCardActivationStatus> {
|
||||
val authorizationTokensResponse = visaAuthRemoteDataSource.getAccessTokens(signedChallenge = signedChallenge)
|
||||
.getOrElse { error ->
|
||||
Timber.i("Failed to get Access token for Wallet public key authorization.")
|
||||
TangemLogger.i("Failed to get Access token for Wallet public key authorization.")
|
||||
return if (
|
||||
error is VisaApiError.ProductInstanceIsNotActivated ||
|
||||
error is VisaApiError.ProductInstanceNotFoundActivationRequired
|
||||
) {
|
||||
Timber.i("Proceeding with card authorization.")
|
||||
TangemLogger.i("Proceeding with card authorization.")
|
||||
handleCardAuthorization(cardWalletAddress = cardWalletAddress)
|
||||
} else {
|
||||
CompletionResult.Failure(error.tangemError)
|
||||
}
|
||||
}
|
||||
|
||||
Timber.i("Authorized using Wallet public key successfully")
|
||||
TangemLogger.i("Authorized using Wallet public key successfully")
|
||||
|
||||
return CompletionResult.Success(VisaCardActivationStatus.Activated(authorizationTokensResponse))
|
||||
}
|
||||
|
|
@ -148,27 +149,27 @@ internal class VisaCardScanHandler @Inject constructor(
|
|||
): CompletionResult<VisaCardActivationStatus> {
|
||||
val card = session.environment.card ?: return CompletionResult.Failure(TangemSdkError.MissingPreflightRead())
|
||||
|
||||
Timber.i("Requesting authorization challenge to sign")
|
||||
TangemLogger.i("Requesting authorization challenge to sign")
|
||||
|
||||
val challengeResponse = visaAuthRemoteDataSource.getCardAuthChallenge(
|
||||
cardId = card.cardId,
|
||||
cardPublicKey = card.cardPublicKey.toHexString(),
|
||||
).getOrElse { error ->
|
||||
Timber.e("Failed to get challenge for Card authorization. Plain error: ${error.errorCode}")
|
||||
TangemLogger.e("Failed to get challenge for Card authorization. Plain error: ${error.errorCode}")
|
||||
return CompletionResult.Failure(error.tangemError)
|
||||
}
|
||||
|
||||
Timber.i("Received challenge to sign: ${challengeResponse.challenge}")
|
||||
TangemLogger.i("Received challenge to sign: ${challengeResponse.challenge}")
|
||||
|
||||
val signChallengeResult = signChallengeWithCard(challenge = challengeResponse.challenge)
|
||||
|
||||
val attestCardKeyResponse = when (signChallengeResult) {
|
||||
is CompletionResult.Success -> {
|
||||
Timber.i("Challenged signed.")
|
||||
TangemLogger.i("Challenged signed.")
|
||||
signChallengeResult.data
|
||||
}
|
||||
is CompletionResult.Failure -> {
|
||||
Timber.e(
|
||||
TangemLogger.e(
|
||||
"Failed to sign challenge with Card public key. Tangem Sdk Error: ${signChallengeResult.error}",
|
||||
)
|
||||
return CompletionResult.Failure(signChallengeResult.error)
|
||||
|
|
@ -181,7 +182,7 @@ internal class VisaCardScanHandler @Inject constructor(
|
|||
salt = attestCardKeyResponse.salt.toHexString(),
|
||||
),
|
||||
).getOrElse { error ->
|
||||
Timber.e("Failed to sign challenge with Card public key. Plain error: ${error.errorCode}")
|
||||
TangemLogger.e("Failed to sign challenge with Card public key. Plain error: ${error.errorCode}")
|
||||
return CompletionResult.Failure(error.tangemError)
|
||||
}
|
||||
|
||||
|
|
@ -191,7 +192,7 @@ internal class VisaCardScanHandler @Inject constructor(
|
|||
)
|
||||
|
||||
val activationRemoteState = visaActivationRepository.getActivationRemoteState().getOrElse { error ->
|
||||
Timber.e("Failed to sign challenge with Card public key. Plain error: ${error.errorCode}")
|
||||
TangemLogger.e("Failed to sign challenge with Card public key. Plain error: ${error.errorCode}")
|
||||
return CompletionResult.Failure(error.tangemError)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue