From 812831937c9a96087fadcbaf1d7f31f0b133776e Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 12 May 2021 21:40:31 +0300 Subject: [PATCH] Updated on 2026-08-14 --- app/build.gradle | 10 +-- .../tap/common/redux/global/GlobalAction.kt | 7 +- .../tap/common/redux/global/GlobalReducer.kt | 23 ++++++- .../com/tangem/tap/domain/TangemSigner.kt | 65 +++++++++++++++++++ .../features/details/redux/DetailsReducer.kt | 5 +- .../features/details/redux/DetailsState.kt | 1 + .../features/details/ui/DetailsFragment.kt | 4 ++ .../send/redux/middlewares/SendMiddleware.kt | 15 ++++- app/src/main/res/layout/fragment_details.xml | 26 +++++++- 9 files changed, 141 insertions(+), 15 deletions(-) create mode 100644 app/src/main/java/com/tangem/tap/domain/TangemSigner.kt diff --git a/app/build.gradle b/app/build.gradle index 44a13aa801..6674f33d44 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -75,13 +75,9 @@ dependencies { implementation 'com.google.android.play:core-ktx:1.8.1' coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5' -// TODO: change to prod dependencies when they are available -// implementation 'com.tangem:blockchain:1.164.0' -// implementation 'com.tangem:core:1.109.0' -// implementation 'com.tangem:sdk:1.109.0' - implementation 'blockchain-sdk-kotlin:blockchain:tangem-20210416.151414-8' - implementation 'com.tangem:tangem-core:tangem-20210414.185224-2' - implementation 'com.tangem:tangem-sdk:tangem-20210414.185231-2' + implementation 'com.tangem:blockchain:develop-5' + implementation 'com.tangem:core:develop-10' + implementation 'com.tangem:sdk:develop-10' // WebView implementation "androidx.browser:browser:1.3.0" diff --git a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalAction.kt b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalAction.kt index 2a2a612757..38f45e4ca7 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalAction.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalAction.kt @@ -24,7 +24,12 @@ sealed class GlobalAction : Action { data class Success(val appCurrency: FiatCurrencyName) : GlobalAction() } - data class UpdateWalletSignedHashes(val walletSignedHashes: Int?) : GlobalAction() + data class UpdateWalletSignedHashes( + val walletSignedHashes: Int?, + val remainingSignatures: Int?, + val walletPublicKey: ByteArray, + ) : GlobalAction() + data class HideWarningMessage(val warning: WarningMessage) : GlobalAction() data class UpdateSecurityOptions(val securityOption: SecurityOption) : GlobalAction() diff --git a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalReducer.kt b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalReducer.kt index 7b7e74d399..c7ed09486a 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalReducer.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalReducer.kt @@ -1,5 +1,6 @@ package com.tangem.tap.common.redux.global +import com.tangem.commands.wallet.WalletIndex import com.tangem.tap.common.redux.AppState import com.tangem.tap.features.details.redux.SecurityOption import org.rekotlin.Action @@ -32,13 +33,13 @@ fun globalReducer(action: Action, state: AppState): GlobalState { is GlobalAction.UpdateSecurityOptions -> { val card = when (action.securityOption) { SecurityOption.LongTap -> globalState.scanNoteResponse?.card?.copy( - isPin1Default = true, isPin2Default = true + isPin1Default = true, isPin2Default = true ) SecurityOption.PassCode -> globalState.scanNoteResponse?.card?.copy( - isPin1Default = true, isPin2Default = false + isPin1Default = true, isPin2Default = false ) SecurityOption.AccessCode -> globalState.scanNoteResponse?.card?.copy( - isPin1Default = false, isPin2Default = true + isPin1Default = false, isPin2Default = true ) } if (card != null) { @@ -47,6 +48,22 @@ fun globalReducer(action: Action, state: AppState): GlobalState { globalState } } + is GlobalAction.UpdateWalletSignedHashes -> { + val wallet = globalState.scanNoteResponse?.card + ?.wallet(WalletIndex.PublicKey(action.walletPublicKey)) + ?.copy( + signedHashes = action.walletSignedHashes, + remainingSignatures = action.remainingSignatures + ) + val card = globalState.scanNoteResponse?.card + wallet?.let { globalState.scanNoteResponse.card.updateWallet(wallet) } + + if (card != null) { + globalState.copy(scanNoteResponse = globalState.scanNoteResponse.copy(card = card)) + } else { + globalState + } + } is GlobalAction.SetFeedbackManager -> { globalState.copy(feedbackManager = action.feedbackManager) } diff --git a/app/src/main/java/com/tangem/tap/domain/TangemSigner.kt b/app/src/main/java/com/tangem/tap/domain/TangemSigner.kt new file mode 100644 index 0000000000..7a3556b33a --- /dev/null +++ b/app/src/main/java/com/tangem/tap/domain/TangemSigner.kt @@ -0,0 +1,65 @@ +package com.tangem.tap.domain + +import com.tangem.Message +import com.tangem.TangemSdk +import com.tangem.blockchain.common.TransactionSigner +import com.tangem.commands.SignCommand +import com.tangem.commands.SignResponse +import com.tangem.commands.wallet.WalletIndex +import com.tangem.common.CompletionResult +import kotlin.coroutines.resume +import kotlin.coroutines.suspendCoroutine + +class TangemSigner( + private val tangemSdk: TangemSdk, + private val initialMessage: Message, + private val signerCallback: (SignResponse) -> Unit +) : TransactionSigner { + + override suspend fun sign( + hash: ByteArray, + cardId: String, + walletPublicKey: ByteArray + ): CompletionResult = + suspendCoroutine { continuation -> + val command = SignCommand(arrayOf(hash), WalletIndex.PublicKey(walletPublicKey)) + tangemSdk.startSessionWithRunnable( + runnable = command, + cardId = cardId, + initialMessage = initialMessage, + ) { result -> + when (result) { + is CompletionResult.Success -> { + signerCallback(result.data) + continuation.resume(CompletionResult.Success(result.data.signatures.first())) + } + is CompletionResult.Failure -> + continuation.resume(CompletionResult.Failure(result.error)) + } + } + } + + + override suspend fun sign( + hashes: List, + cardId: String, + walletPublicKey: ByteArray + ): CompletionResult> = + suspendCoroutine { continuation -> + val command = SignCommand(hashes.toTypedArray(), WalletIndex.PublicKey(walletPublicKey)) + tangemSdk.startSessionWithRunnable( + runnable = command, + cardId = cardId, + initialMessage = initialMessage, + ) { result -> + when (result) { + is CompletionResult.Success -> { + signerCallback(result.data) + continuation.resume(CompletionResult.Success(result.data.signatures)) + } + is CompletionResult.Failure -> + continuation.resume(CompletionResult.Failure(result.error)) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt index 4ec1681b66..a699f2ee45 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt @@ -5,6 +5,7 @@ import com.tangem.commands.common.card.Card import com.tangem.commands.common.card.masks.Settings import com.tangem.tap.common.redux.AppState import com.tangem.tap.domain.TapWorkarounds +import com.tangem.tap.domain.extensions.signedHashesCount import com.tangem.tap.domain.extensions.toSendableAmounts import com.tangem.tap.domain.twins.TwinsHelper import com.tangem.tap.domain.twins.isTwinCard @@ -203,5 +204,5 @@ private fun prepareAllowedSecurityOptions(card: Card): EnumSet { private fun Card.toCardInfo(): CardInfo? { val cardId = this.cardId.chunked(4).joinToString(separator = " ") val issuer = this.cardData?.issuerName ?: return null - return CardInfo(cardId, issuer) -} \ No newline at end of file + val signedHashes = this.signedHashesCount() + return CardInfo(cardId, issuer, signedHashes)} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsState.kt b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsState.kt index 22fca3db45..5ef1033e2f 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsState.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsState.kt @@ -26,6 +26,7 @@ data class DetailsState( data class CardInfo( val cardId: String, val issuer: String, + val signedHashes: Int, ) enum class EraseWalletState { Allowed, NotAllowedByCard, NotEmpty } diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/DetailsFragment.kt b/app/src/main/java/com/tangem/tap/features/details/ui/DetailsFragment.kt index fc793be4cc..895f379b09 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/DetailsFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/DetailsFragment.kt @@ -74,8 +74,12 @@ class DetailsFragment : Fragment(R.layout.fragment_details), StoreSubscriber + store.dispatch( + GlobalAction.UpdateWalletSignedHashes( + walletSignedHashes = signResponse.walletSignedHashes, + remainingSignatures = signResponse.walletRemainingSignatures, + walletPublicKey = walletManager.wallet.publicKey + ) + ) + } val result = (walletManager as TransactionSender).send(txData, signer) withContext(Dispatchers.Main) { when (result) { diff --git a/app/src/main/res/layout/fragment_details.xml b/app/src/main/res/layout/fragment_details.xml index 69b8b5cf55..fc33c31d7d 100644 --- a/app/src/main/res/layout/fragment_details.xml +++ b/app/src/main/res/layout/fragment_details.xml @@ -90,6 +90,30 @@ app:layout_constraintTop_toBottomOf="@id/tv_card_id" tools:text="Tangem" /> + + + + + app:layout_constraintTop_toBottomOf="@id/tv_signed_hashes_title" />