From 7c91472d9960f9a92044fec139c30ecb81df6253 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 17 Jun 2025 11:20:30 +0300 Subject: [PATCH] Updated on 2026-08-14 --- .../tap/domain/visa/VisaCardScanHandler.kt | 24 +++++++++++-------- .../GenerateNoneByCardWalletRequest.kt | 1 + .../GetAccessTokenByCardWalletRequest.kt | 1 + .../data/visa/DefaultVisaAuthRepository.kt | 3 +++ .../domain/visa/model/VisaAuthChallenge.kt | 3 ++- .../visa/model/VisaAuthSignedChallenge.kt | 1 + .../visa/repository/VisaAuthRepository.kt | 5 +++- 7 files changed, 26 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/domain/visa/VisaCardScanHandler.kt b/app/src/main/java/com/tangem/tap/domain/visa/VisaCardScanHandler.kt index 46a8dadc5e..4d9a809e11 100644 --- a/app/src/main/java/com/tangem/tap/domain/visa/VisaCardScanHandler.kt +++ b/app/src/main/java/com/tangem/tap/domain/visa/VisaCardScanHandler.kt @@ -83,11 +83,14 @@ internal class VisaCardScanHandler @Inject constructor( Timber.i("Requesting challenge for wallet authorization") - val challengeResponse = visaAuthRepository.getCardWalletAuthChallenge(cardWalletAddress = walletAddress.value) - .getOrElse { - Timber.i("Failed to get Access token for Wallet public key authorization") - return CompletionResult.Failure(it.tangemError) - } + val challengeResponse = visaAuthRepository.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 { + Timber.i("Failed to get Access token for Wallet public key authorization") + return CompletionResult.Failure(it.tangemError) + } val signChallengeResult = signChallengeWithWallet( publicKey = wallet.publicKey, @@ -96,15 +99,16 @@ internal class VisaCardScanHandler @Inject constructor( return when (signChallengeResult) { is CompletionResult.Success -> { - val signature = signChallengeResult.data.cardSignature ?: run { - Timber.i("Failed to sign challenge with Wallet public key") - return CompletionResult.Failure(VisaCardScanError.FailedToSignChallenge.tangemError) - } + val signature = signChallengeResult.data.walletSignature + val salt = signChallengeResult.data.salt Timber.i("Challenge signed with Wallet public key") handleWalletAuthorizationTokens( cardWalletAddress = walletAddress.value, - signedChallenge = challengeResponse.toSignedChallenge(signature.toHexString()), + signedChallenge = challengeResponse.toSignedChallenge( + signedChallenge = signature.toHexString(), + salt = salt.toHexString(), + ), ) } is CompletionResult.Failure -> { diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/visa/models/request/GenerateNoneByCardWalletRequest.kt b/core/datasource/src/main/java/com/tangem/datasource/api/visa/models/request/GenerateNoneByCardWalletRequest.kt index 172c39e727..69c2f7a7d5 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/api/visa/models/request/GenerateNoneByCardWalletRequest.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/api/visa/models/request/GenerateNoneByCardWalletRequest.kt @@ -7,4 +7,5 @@ import com.squareup.moshi.JsonClass data class GenerateNoneByCardWalletRequest( @Json(name = "auth_type") val authType: String = "card_wallet", @Json(name = "card_wallet_address") val cardWalletAddress: String, + @Json(name = "card_id") val cardId: String, ) \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/visa/models/request/GetAccessTokenByCardWalletRequest.kt b/core/datasource/src/main/java/com/tangem/datasource/api/visa/models/request/GetAccessTokenByCardWalletRequest.kt index c80e97b0c9..df5d0c3935 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/api/visa/models/request/GetAccessTokenByCardWalletRequest.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/api/visa/models/request/GetAccessTokenByCardWalletRequest.kt @@ -8,4 +8,5 @@ data class GetAccessTokenByCardWalletRequest( @Json(name = "auth_type") val authType: String = "card_wallet", @Json(name = "session_id") val sessionId: String, @Json(name = "signature") val signature: String, + @Json(name = "salt") val salt: String, ) \ No newline at end of file diff --git a/data/visa/src/main/kotlin/com/tangem/data/visa/DefaultVisaAuthRepository.kt b/data/visa/src/main/kotlin/com/tangem/data/visa/DefaultVisaAuthRepository.kt index a0b6429f32..b0f2b5e284 100644 --- a/data/visa/src/main/kotlin/com/tangem/data/visa/DefaultVisaAuthRepository.kt +++ b/data/visa/src/main/kotlin/com/tangem/data/visa/DefaultVisaAuthRepository.kt @@ -47,12 +47,14 @@ internal class DefaultVisaAuthRepository @Inject constructor( } override suspend fun getCardWalletAuthChallenge( + cardId: String, cardWalletAddress: String, ): Either = withContext(dispatchers.io) { request { visaAuthApi.generateNonceByCardWallet( GenerateNoneByCardWalletRequest( cardWalletAddress = cardWalletAddress, + cardId = cardId, ), ).getOrThrow() }.map { response -> @@ -82,6 +84,7 @@ internal class DefaultVisaAuthRepository @Inject constructor( GetAccessTokenByCardWalletRequest( sessionId = signedChallenge.challenge.session.sessionId, signature = signedChallenge.signature, + salt = signedChallenge.salt, ), ).getOrThrow() } diff --git a/domain/visa/models/src/main/kotlin/com/tangem/domain/visa/model/VisaAuthChallenge.kt b/domain/visa/models/src/main/kotlin/com/tangem/domain/visa/model/VisaAuthChallenge.kt index 536b7207dc..eebd03482d 100644 --- a/domain/visa/models/src/main/kotlin/com/tangem/domain/visa/model/VisaAuthChallenge.kt +++ b/domain/visa/models/src/main/kotlin/com/tangem/domain/visa/model/VisaAuthChallenge.kt @@ -23,9 +23,10 @@ fun VisaAuthChallenge.Card.toSignedChallenge(signedChallenge: String, salt: Stri ) } -fun VisaAuthChallenge.Wallet.toSignedChallenge(signedChallenge: String): VisaAuthSignedChallenge { +fun VisaAuthChallenge.Wallet.toSignedChallenge(signedChallenge: String, salt: String): VisaAuthSignedChallenge { return VisaAuthSignedChallenge.ByWallet( challenge = this, signature = signedChallenge, + salt = salt, ) } \ No newline at end of file diff --git a/domain/visa/models/src/main/kotlin/com/tangem/domain/visa/model/VisaAuthSignedChallenge.kt b/domain/visa/models/src/main/kotlin/com/tangem/domain/visa/model/VisaAuthSignedChallenge.kt index a16916a887..607dabccbb 100644 --- a/domain/visa/models/src/main/kotlin/com/tangem/domain/visa/model/VisaAuthSignedChallenge.kt +++ b/domain/visa/models/src/main/kotlin/com/tangem/domain/visa/model/VisaAuthSignedChallenge.kt @@ -11,5 +11,6 @@ sealed class VisaAuthSignedChallenge { data class ByWallet( val challenge: VisaAuthChallenge.Wallet, val signature: String, + val salt: String, ) : VisaAuthSignedChallenge() } \ No newline at end of file diff --git a/domain/visa/src/main/kotlin/com/tangem/domain/visa/repository/VisaAuthRepository.kt b/domain/visa/src/main/kotlin/com/tangem/domain/visa/repository/VisaAuthRepository.kt index 256587dce1..f7f19ca0e9 100644 --- a/domain/visa/src/main/kotlin/com/tangem/domain/visa/repository/VisaAuthRepository.kt +++ b/domain/visa/src/main/kotlin/com/tangem/domain/visa/repository/VisaAuthRepository.kt @@ -13,7 +13,10 @@ interface VisaAuthRepository { cardPublicKey: String, ): Either - suspend fun getCardWalletAuthChallenge(cardWalletAddress: String): Either + suspend fun getCardWalletAuthChallenge( + cardId: String, + cardWalletAddress: String, + ): Either suspend fun getAccessTokens(signedChallenge: VisaAuthSignedChallenge): Either