diff --git a/domain/src/main/java/com/tangem/domain/common/LogConfig.kt b/domain/src/main/java/com/tangem/domain/common/LogConfig.kt index 56c2950141..ff11351635 100644 --- a/domain/src/main/java/com/tangem/domain/common/LogConfig.kt +++ b/domain/src/main/java/com/tangem/domain/common/LogConfig.kt @@ -13,5 +13,6 @@ object NetworkLogConfig { val mercuryoService: Boolean = false val moonPayService: Boolean = false val tangemTechService: Boolean = BuildConfig.DEBUG + val paymentologyApiService: Boolean = BuildConfig.DEBUG val blockchainSdkNetwork: Boolean = BuildConfig.DEBUG } \ No newline at end of file diff --git a/network/src/main/java/com/tangem/network/api/paymentology/PaymentologyApi.kt b/network/src/main/java/com/tangem/network/api/paymentology/PaymentologyApi.kt new file mode 100644 index 0000000000..cbefd39af8 --- /dev/null +++ b/network/src/main/java/com/tangem/network/api/paymentology/PaymentologyApi.kt @@ -0,0 +1,29 @@ +package com.tangem.network.api.paymentology + +import retrofit2.http.Body +import retrofit2.http.POST + +/** +[REDACTED_AUTHOR] + */ +interface PaymentologyApi { + + @POST("card/verify") + fun checkRegistration( + @Body request: CheckRegistrationRequests, + ): RegistrationResponse.Item + + @POST("card/get_challenge") + fun requestAttestationChallenge( + @Body request: CheckRegistrationRequests.Item, + ): AttestationResponse + + @POST("card/set_pin") + fun registerWallet( + @Body request: RegisterWalletRequest, + ): RegisterWalletResponse + + companion object { + val baseUrl: String = "https://paymentologygate.oa.r.appspot.com/" + } +} \ No newline at end of file diff --git a/network/src/main/java/com/tangem/network/api/paymentology/PaymentologyApiService.kt b/network/src/main/java/com/tangem/network/api/paymentology/PaymentologyApiService.kt new file mode 100644 index 0000000000..0fce5b41ba --- /dev/null +++ b/network/src/main/java/com/tangem/network/api/paymentology/PaymentologyApiService.kt @@ -0,0 +1,44 @@ +package com.tangem.network.api.paymentology + +import com.tangem.common.extensions.toHexString +import com.tangem.common.services.Result +import com.tangem.common.services.performRequest +import com.tangem.network.common.createRetrofitInstance +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext + +/** +[REDACTED_AUTHOR] + */ +class PaymentologyApiService( + private val logEnabled: Boolean, +) { + private val api = createRetrofitInstance( + baseUrl = PaymentologyApi.baseUrl, + logEnabled = logEnabled, + ).create(PaymentologyApi::class.java) + + suspend fun checkRegistration( + cardId: String, + publicKey: ByteArray, + ): Result = withContext(Dispatchers.IO) { + // later convert response to SaltPayRegistrator.State + val requestItem = CheckRegistrationRequests.Item(cardId, publicKey.toHexString()) + val requests = listOf(requestItem) + performRequest { api.checkRegistration(CheckRegistrationRequests(requests)) } + } + + suspend fun requestAttestationChallenge( + cardId: String, + publicKey: ByteArray, + ): Result = withContext(Dispatchers.IO) { + val requestItem = CheckRegistrationRequests.Item(cardId, publicKey.toHexString()) + performRequest { api.requestAttestationChallenge(requestItem) } + } + + suspend fun registerWallet( + request: RegisterWalletRequest, + ): Result = withContext(Dispatchers.IO) { + performRequest { api.registerWallet(request) } + } +} \ No newline at end of file diff --git a/network/src/main/java/com/tangem/network/api/paymentology/Requests.kt b/network/src/main/java/com/tangem/network/api/paymentology/Requests.kt new file mode 100644 index 0000000000..1cea8aada4 --- /dev/null +++ b/network/src/main/java/com/tangem/network/api/paymentology/Requests.kt @@ -0,0 +1,59 @@ +package com.tangem.network.api.paymentology + +import com.squareup.moshi.Json +import com.tangem.common.extensions.calculateHashCode + +/** +[REDACTED_AUTHOR] + */ +data class CheckRegistrationRequests( + val requests: List, +) { + data class Item( + @Json(name = "CID") + var cardId: String = "", + var publicKey: String = "", + ) +} + +data class RegisterWalletRequest( + @Json(name = "CID") + val cardId: String, + val publicKey: ByteArray, + val walletPublicKey: ByteArray, + val walletSalt: ByteArray, + val walletSignature: ByteArray, + val cardSalt: ByteArray, + val cardSignature: ByteArray, + @Json(name = "PIN") + val pin: String, +) { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as RegisterWalletRequest + + if (cardId != other.cardId) return false + if (publicKey.contentEquals(other.publicKey)) return false + if (walletPublicKey.contentEquals(other.walletPublicKey)) return false + if (walletSalt.contentEquals(other.walletSalt)) return false + if (walletSignature.contentEquals(other.walletSignature)) return false + if (cardSalt.contentEquals(other.cardSalt)) return false + if (cardSignature.contentEquals(other.cardSignature)) return false + if (pin != other.pin) return false + + return true + } + + override fun hashCode(): Int = calculateHashCode( + cardId.hashCode(), + publicKey.contentHashCode(), + walletPublicKey.contentHashCode(), + walletSalt.contentHashCode(), + walletSignature.contentHashCode(), + cardSalt.contentHashCode(), + cardSignature.contentHashCode(), + pin.hashCode(), + ) +} \ No newline at end of file diff --git a/network/src/main/java/com/tangem/network/api/paymentology/Responses.kt b/network/src/main/java/com/tangem/network/api/paymentology/Responses.kt new file mode 100644 index 0000000000..7edd003b23 --- /dev/null +++ b/network/src/main/java/com/tangem/network/api/paymentology/Responses.kt @@ -0,0 +1,72 @@ +package com.tangem.network.api.paymentology + +import com.squareup.moshi.Json +import com.tangem.common.extensions.calculateHashCode + +/** +[REDACTED_AUTHOR] + */ +interface ErrorContainer { + val error: String? +} + +data class RegistrationResponse( + val results: List, + val success: Boolean, + override val error: String?, + val errorCode: String?, +) : ErrorContainer { + + data class Item( + @Json(name = "CID") + val cardId: String, + val passed: Boolean?, + val active: Boolean?, + @Json(name = "pin_set") + val pinSet: Boolean?, + @Json(name = "blockchain_init") + val blockchainInit: Boolean?, + @Json(name = "kyc_passed") + val kycPassed: Boolean?, + @Json(name = "kyc_waiting") + val kycWaiting: Boolean?, + @Json(name = "disabled_by_admin") + val disabledByAdmin: Boolean?, + override val error: String?, + ) : ErrorContainer +} + +data class AttestationResponse( + val challenge: ByteArray, + val success: Boolean, + override val error: String?, + val errorCode: String?, +) : ErrorContainer { + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as AttestationResponse + + if (challenge.contentEquals(other.challenge)) return false + if (success != other.success) return false + if (error != other.error) return false + if (errorCode != other.errorCode) return false + + return true + } + + override fun hashCode(): Int = calculateHashCode( + challenge.contentHashCode(), + success.hashCode(), + error.hashCode(), + errorCode.hashCode(), + ) +} + +data class RegisterWalletResponse( + val success: Boolean, + override val error: String?, + val errorCode: String?, +) : ErrorContainer \ No newline at end of file