diff --git a/app/src/main/java/com/tangem/tap/domain/tasks/visa/VisaCardActivationTask.kt b/app/src/main/java/com/tangem/tap/domain/tasks/visa/VisaCardActivationTask.kt index 9bd9bf2e48..f8b20f31d0 100644 --- a/app/src/main/java/com/tangem/tap/domain/tasks/visa/VisaCardActivationTask.kt +++ b/app/src/main/java/com/tangem/tap/domain/tasks/visa/VisaCardActivationTask.kt @@ -8,6 +8,7 @@ import com.tangem.common.core.TangemSdkError import com.tangem.common.extensions.hexToBytes import com.tangem.common.extensions.toHexString import com.tangem.common.map +import com.tangem.common.timemeasure.RealtimeMonotonicTimeSource import com.tangem.crypto.CryptoUtils import com.tangem.datasource.local.visa.VisaAuthTokenStorage import com.tangem.datasource.local.visa.VisaOTPStorage @@ -29,6 +30,7 @@ import kotlinx.coroutines.* import timber.log.Timber import kotlin.coroutines.resume import kotlin.jvm.Throws +import kotlin.time.measureTimedValue @Suppress("LongParameterList") class VisaCardActivationTask @AssistedInject constructor( @@ -69,31 +71,38 @@ class VisaCardActivationTask @AssistedInject constructor( session = session, ) - return if (challengeToSign != null) { - context.signAuthorizationChallenge(challengeToSign) - } else { - val activationOrder = runCatching { visaActivationRepository.getActivationOrderToSign() } - .getOrElse { - return CompletionResult.Failure(TangemSdkError.Underlying(it.message ?: "")) - } + val timedResult = RealtimeMonotonicTimeSource.measureTimedValue { + if (challengeToSign != null) { + context.signAuthorizationChallenge(challengeToSign) + } else { + val activationOrder = runCatching { visaActivationRepository.getActivationOrderToSign() } + .getOrElse { + return CompletionResult.Failure(TangemSdkError.Underlying(it.message ?: "")) + } - context.signOrder(activationOrder) + context.signOrder(activationOrder) + } } + Timber.i("VisaCardActivationTask all time: ${timedResult.duration}") + return timedResult.value } private suspend fun SessionContext.signAuthorizationChallenge( challengeToSign: VisaAuthChallenge.Card, ): CompletionResult { val attestationCommand = AttestCardKeyCommand(challenge = CryptoUtils.generateRandomBytes(length = 16)) - val result = suspendCancellableCoroutine { continuation -> - attestationCommand.run(session = session) { attestationResponse -> - continuation.resume(attestationResponse) + val timedResult = RealtimeMonotonicTimeSource.measureTimedValue { + suspendCancellableCoroutine { continuation -> + attestationCommand.run(session = session) { attestationResponse -> + continuation.resume(attestationResponse) + } } } + Timber.i("AttestCardKeyCommand time: ${timedResult.duration}") - return when (result) { + return when (val result = timedResult.value) { is CompletionResult.Success -> { - Timber.tag("ASDASD").e("AttestCardKeyCommand success") + Timber.i("AttestCardKeyCommand success") processSignedAuthorizationChallenge( signedChallenge = challengeToSign.toSignedChallenge( signedChallenge = result.data.cardSignature.toHexString(), @@ -102,7 +111,7 @@ class VisaCardActivationTask @AssistedInject constructor( ) } is CompletionResult.Failure -> { - Timber.tag("ASDASD").e("AttestCardKeyCommand failure ${result.error}") + Timber.e("AttestCardKeyCommand failure ${result.error}") CompletionResult.Failure(result.error) } } @@ -153,19 +162,24 @@ class VisaCardActivationTask @AssistedInject constructor( createOTP(session) } else { val createWalletTask = CreateWalletTask(VisaUtilities.mandatoryCurve) - val result = suspendCancellableCoroutine { continuation -> - createWalletTask.run(session) { createWalletResult -> - continuation.resume(createWalletResult) + + val timedResult = RealtimeMonotonicTimeSource.measureTimedValue { + suspendCancellableCoroutine { continuation -> + createWalletTask.run(session) { createWalletResult -> + continuation.resume(createWalletResult) + } } } - when (result) { + Timber.i("CreateWalletTask time: ${timedResult.duration}") + + when (val result = timedResult.value) { is CompletionResult.Success -> { - Timber.tag("ASDASD").e("CreateWalletTask success") + Timber.i("CreateWalletTask success") createOTP(session) } is CompletionResult.Failure -> { - Timber.tag("ASDASD").e("CreateWalletTask failure ${result.error}") + Timber.e("CreateWalletTask failure ${result.error}") CompletionResult.Failure(result.error) } } @@ -179,20 +193,24 @@ class VisaCardActivationTask @AssistedInject constructor( CompletionResult.Success(Unit) } else { val otpCommand = GenerateOTPCommand() - val result = suspendCancellableCoroutine { continuation -> - otpCommand.run(session) { otpResult -> - continuation.resume(otpResult) + val timedResult = RealtimeMonotonicTimeSource.measureTimedValue { + suspendCancellableCoroutine { continuation -> + otpCommand.run(session) { otpResult -> + continuation.resume(otpResult) + } } } - when (result) { + Timber.i("GenerateOTPCommand time: ${timedResult.duration}") + + when (val result = timedResult.value) { is CompletionResult.Success -> { - Timber.tag("ASDASD").e("GenerateOTPCommand success") + Timber.i("GenerateOTPCommand success") otpStorage.saveOTP(cardId, result.data.rootOTP) CompletionResult.Success(Unit) } is CompletionResult.Failure -> { - Timber.tag("ASDASD").e("GenerateOTPCommand failure ${result.error}") + Timber.e("GenerateOTPCommand failure ${result.error}") CompletionResult.Failure(result.error) } } @@ -212,22 +230,26 @@ class VisaCardActivationTask @AssistedInject constructor( derivationPath = VisaUtilities.visaDefaultDerivationPath, ) - val result = suspendCancellableCoroutine { continuation -> - task.run(session) { signResult -> - continuation.resume(signResult) + val timedResult = RealtimeMonotonicTimeSource.measureTimedValue { + suspendCancellableCoroutine { continuation -> + task.run(session) { signResult -> + continuation.resume(signResult) + } } } - return when (result) { + Timber.i("SignHashCommand time: ${timedResult.duration}") + + return when (val result = timedResult.value) { is CompletionResult.Success -> { - Timber.tag("ASDASD").e("SignHashCommand success") + Timber.i("SignHashCommand success") handleSignedOrder( activationOrder = order, response = result.data, ) } is CompletionResult.Failure -> { - Timber.tag("ASDASD").e("SignHashCommand failure ${result.error}") + Timber.e("SignHashCommand failure ${result.error}") CompletionResult.Failure(result.error) } } @@ -261,22 +283,27 @@ class VisaCardActivationTask @AssistedInject constructor( return CompletionResult.Success(Unit) } - Timber.tag("ASDASD").e("Setting access code: $accessCode") + Timber.i("Setting access code") val task = SetUserCodeCommand.changeAccessCode(accessCode) - val result = suspendCancellableCoroutine { continuation -> - task.run(session) { setAccessCodeResult -> - continuation.resume(setAccessCodeResult) + + val timedResult = RealtimeMonotonicTimeSource.measureTimedValue { + suspendCancellableCoroutine { continuation -> + task.run(session) { setAccessCodeResult -> + continuation.resume(setAccessCodeResult) + } } } - return when (result) { + Timber.i("SetUserCodeCommand time: ${timedResult.duration}") + + return when (val result = timedResult.value) { is CompletionResult.Success -> { - Timber.tag("ASDASD").e("SetUserCodeCommand success") + Timber.i("SetUserCodeCommand success") CompletionResult.Success(Unit) } is CompletionResult.Failure -> { - Timber.tag("ASDASD").e("SetUserCodeCommand failure ${result.error}") + Timber.i("SetUserCodeCommand failure ${result.error}") CompletionResult.Failure(result.error) } } 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 d1e883bcdd..42e9b20d4a 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 @@ -1,10 +1,10 @@ package com.tangem.tap.domain.visa import com.tangem.common.CompletionResult -import com.tangem.common.card.Card import com.tangem.common.card.CardWallet import com.tangem.common.core.CardSession import com.tangem.common.core.TangemSdkError +import com.tangem.common.extensions.hexToBytes import com.tangem.common.extensions.toHexString import com.tangem.crypto.hdWallet.DerivationPath import com.tangem.crypto.hdWallet.bip32.ExtendedPublicKey @@ -258,33 +258,26 @@ internal class VisaCardScanHandler @Inject constructor( derivationPath: DerivationPath, nonce: String, ): CompletionResult { - val signHashCommand = SignHashCommand(publicKey, nonce.toByteArray(), derivationPath) - val result = suspendCancellableCoroutine { + val signHashCommand = SignHashCommand( + hash = nonce.hexToBytes(), + walletPublicKey = publicKey, + derivationPath = derivationPath, + ) + return suspendCancellableCoroutine { signHashCommand.run(session) { result -> it.resume(result) } } - - return result } private suspend fun SessionContext.signChallengeWithCard( challenge: String, ): CompletionResult { - val signHashCommand = AttestCardKeyCommand(challenge = challenge.toByteArray()) - val result = suspendCancellableCoroutine { continuation -> + val signHashCommand = AttestCardKeyCommand(challenge = challenge.hexToBytes()) + return suspendCancellableCoroutine { continuation -> signHashCommand.run(session) { result -> continuation.resume(result) } } - - return when (result) { - is CompletionResult.Success -> { - CompletionResult.Success(result.data) - } - is CompletionResult.Failure -> { - CompletionResult.Failure(result.error) - } - } } } \ No newline at end of file diff --git a/common/src/main/kotlin/com/tangem/common/timemeasure/RealtimeMonotonicTimeSource.kt b/common/src/main/kotlin/com/tangem/common/timemeasure/RealtimeMonotonicTimeSource.kt new file mode 100644 index 0000000000..0c2858265c --- /dev/null +++ b/common/src/main/kotlin/com/tangem/common/timemeasure/RealtimeMonotonicTimeSource.kt @@ -0,0 +1,9 @@ +package com.tangem.common.timemeasure + +import android.os.SystemClock +import kotlin.time.AbstractLongTimeSource +import kotlin.time.DurationUnit + +object RealtimeMonotonicTimeSource : AbstractLongTimeSource(DurationUnit.NANOSECONDS) { + override fun read(): Long = SystemClock.elapsedRealtimeNanos() +} \ No newline at end of file diff --git a/data/visa/src/main/kotlin/com/tangem/data/visa/DefaultVisaActivationRepository.kt b/data/visa/src/main/kotlin/com/tangem/data/visa/DefaultVisaActivationRepository.kt index b4cf7f4d8f..4384fc3d0e 100644 --- a/data/visa/src/main/kotlin/com/tangem/data/visa/DefaultVisaActivationRepository.kt +++ b/data/visa/src/main/kotlin/com/tangem/data/visa/DefaultVisaActivationRepository.kt @@ -14,6 +14,7 @@ import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import kotlinx.coroutines.withContext +@Suppress("UnusedPrivateMember") internal class DefaultVisaActivationRepository @AssistedInject constructor( @Assisted private val cardId: String, private val visaApi: TangemVisaApi, @@ -38,7 +39,7 @@ internal class DefaultVisaActivationRepository @AssistedInject constructor( } override suspend fun getActivationOrderToSign(): ActivationOrder = withContext(dispatcherProvider.io) { - ActivationOrder(CryptoUtils.generateRandomBytes(32).toHexString()) + ActivationOrder(CryptoUtils.generateRandomBytes(length = 32).toHexString()) } @AssistedFactory 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 042d5d5518..a4646bf7b6 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 @@ -12,6 +12,7 @@ import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.coroutines.withContext import javax.inject.Inject +@Suppress("UnusedPrivateMember") internal class DefaultVisaAuthRepository @Inject constructor( private val visaAuthApi: TangemVisaAuthApi, private val dispatchers: CoroutineDispatcherProvider, @@ -30,7 +31,7 @@ internal class DefaultVisaAuthRepository @Inject constructor( // ) VisaAuthChallenge.Card( - challenge = CryptoUtils.generateRandomBytes(16).toHexString(), + challenge = CryptoUtils.generateRandomBytes(length = 16).toHexString(), session = VisaAuthSession("session"), ) } @@ -49,7 +50,7 @@ internal class DefaultVisaAuthRepository @Inject constructor( // session = VisaAuthSession(response.sessionId), // ) VisaAuthChallenge.Wallet( - challenge = CryptoUtils.generateRandomBytes(32).toHexString(), + challenge = CryptoUtils.generateRandomBytes(length = 32).toHexString(), session = VisaAuthSession("session"), ) } diff --git a/domain/legacy/src/main/java/com/tangem/domain/common/visa/VisaUtilities.kt b/domain/legacy/src/main/java/com/tangem/domain/common/visa/VisaUtilities.kt index b84ed4f673..d62fffa929 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/common/visa/VisaUtilities.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/common/visa/VisaUtilities.kt @@ -16,7 +16,8 @@ object VisaUtilities { val visaBlockchain = Blockchain.Polygon - val visaDefaultDerivationPath = visaBlockchain.derivationPath(DerivationStyle.V3) + val visaDefaultDerivationPath + get() = visaBlockchain.derivationPath(DerivationStyle.V3) fun visaDefaultDerivationPath(style: DerivationStyle) = visaBlockchain.derivationPath(style) diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/visa/impl/child/accesscode/OnboardingVisaAccessCodeComponent.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/visa/impl/child/accesscode/OnboardingVisaAccessCodeComponent.kt index dd7a6f2ed6..6508b14557 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/visa/impl/child/accesscode/OnboardingVisaAccessCodeComponent.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/visa/impl/child/accesscode/OnboardingVisaAccessCodeComponent.kt @@ -8,7 +8,6 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.tangem.core.decompose.context.AppComponentContext import com.tangem.core.decompose.model.getOrCreateModel import com.tangem.core.ui.decompose.ComposableContentComponent -import com.tangem.core.ui.security.DisableScreenshotsDisposableEffect import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.visa.model.VisaDataForApprove import com.tangem.features.onboarding.v2.visa.impl.DefaultOnboardingVisaComponent @@ -44,7 +43,7 @@ internal class OnboardingVisaAccessCodeComponent( BackHandler(onBack = model::onBack) - DisableScreenshotsDisposableEffect() + // DisableScreenshotsDisposableEffect() OnboardingVisaAccessCode(state, modifier) } diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/visa/impl/child/accesscode/model/OnboardingVisaAccessCodeModel.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/visa/impl/child/accesscode/model/OnboardingVisaAccessCodeModel.kt index b621996c87..01ed148a2f 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/visa/impl/child/accesscode/model/OnboardingVisaAccessCodeModel.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/visa/impl/child/accesscode/model/OnboardingVisaAccessCodeModel.kt @@ -17,7 +17,6 @@ import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch import javax.inject.Inject -import kotlin.math.tan @Stable @ComponentScoped