Updated on 2026-08-14

This commit is contained in:
Tangem 2026-06-05 12:32:13 +04:00
parent fa55c16871
commit 85b00c4c65
18 changed files with 269 additions and 16 deletions

View file

@ -1,5 +1,6 @@
package com.tangem.tap.common.libs.blockchainsdk
import androidx.annotation.VisibleForTesting
import com.tangem.Message
import com.tangem.TangemSdk
import com.tangem.blockchain.common.TransactionSigner
@ -7,22 +8,70 @@ import com.tangem.core.analytics.models.Basic.TransactionSent.WalletForm
import com.tangem.core.analytics.store.LastSignedWalletFormStore
import com.tangem.data.card.TransactionSignerFactory
import com.tangem.domain.card.models.TwinKey
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.domain.common.wallets.update
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.tap.domain.TangemSigner
import com.tangem.tap.domain.TangemSignerResponse
import com.tangem.utils.coroutines.AppCoroutineScope
import kotlinx.coroutines.launch
internal class DefaultTransactionSignerFactory(
private val lastSignedWalletFormStore: LastSignedWalletFormStore,
private val userWalletsListRepository: UserWalletsListRepository,
private val coroutineScope: AppCoroutineScope,
) : TransactionSignerFactory {
override fun createTransactionSigner(cardId: String?, sdk: TangemSdk, twinKey: TwinKey?): TransactionSigner {
override fun createTransactionSigner(
cardId: String?,
sdk: TangemSdk,
twinKey: TwinKey?,
userWalletId: UserWalletId,
): TransactionSigner {
return TangemSigner(
cardId = cardId,
tangemSdk = sdk,
initialMessage = Message(),
twinKey = twinKey,
) { signResponse ->
lastSignedWalletFormStore.update(
if (signResponse.isRing) WalletForm.Ring else WalletForm.Card,
)
onSignerResponse(userWalletId, signResponse)
}
}
@VisibleForTesting
internal fun onSignerResponse(userWalletId: UserWalletId, signResponse: TangemSignerResponse) {
lastSignedWalletFormStore.update(
if (signResponse.isRing) WalletForm.Ring else WalletForm.Card,
)
coroutineScope.launch {
userWalletsListRepository.update(userWalletId) { userWallet ->
userWallet.updateSignedHashes(signResponse)
}
}
}
private fun UserWallet.updateSignedHashes(signResponse: TangemSignerResponse): UserWallet {
if (this !is UserWallet.Cold) return this
return copy(
scanResponse = scanResponse.copy(
card = scanResponse.card.copy(
wallets = scanResponse.card.wallets.map { wallet ->
if (wallet.publicKey.contentEquals(signResponse.signedWalletPublicKey)) {
wallet.copy(
// Keep previously known counters if the signer response does not provide them,
// otherwise we would regress the UI counters to null.
totalSignedHashes = signResponse.totalSignedHashes ?: wallet.totalSignedHashes,
remainingSignatures = signResponse.remainingSignatures ?: wallet.remainingSignatures,
)
} else {
wallet
}
},
),
),
)
}
}

View file

@ -51,6 +51,7 @@ internal object WalletConnectDomainModule {
cardSdkConfigRepository.getCommonSigner(
cardId = card.cardId.takeIf { isCardNotBackedUp },
twinKey = TwinKey.getOrNull(scanResponse = wallet.scanResponse),
userWalletId = wallet.walletId,
)
}
}

View file

@ -2,7 +2,9 @@ package com.tangem.tap.di.libs.blockchainsdk
import com.tangem.core.analytics.store.LastSignedWalletFormStore
import com.tangem.data.card.TransactionSignerFactory
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.tap.common.libs.blockchainsdk.DefaultTransactionSignerFactory
import com.tangem.utils.coroutines.AppCoroutineScope
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
@ -20,7 +22,13 @@ internal class TransactionSignerFactoryModule {
@Singleton
fun provideTransactionSignerFactory(
lastSignedWalletFormStore: LastSignedWalletFormStore,
userWalletsListRepository: UserWalletsListRepository,
appCoroutineScope: AppCoroutineScope,
): TransactionSignerFactory {
return DefaultTransactionSignerFactory(lastSignedWalletFormStore)
return DefaultTransactionSignerFactory(
lastSignedWalletFormStore = lastSignedWalletFormStore,
userWalletsListRepository = userWalletsListRepository,
coroutineScope = appCoroutineScope,
)
}
}

View file

@ -40,6 +40,7 @@ class TangemSigner(
totalSignedHashes = result.data.totalSignedHashes,
remainingSignatures = result.data.remainingSignatures,
isRing = result.data.batchId?.let(::isRing) == true,
signedWalletPublicKey = publicKey.seedKey,
),
)
if (continuation.isActive) {
@ -86,6 +87,7 @@ class TangemSigner(
totalSignedHashes = result.data.totalSignedHashes,
remainingSignatures = result.data.remainingSignatures,
isRing = result.data.batchId?.let(::isRing) == true,
signedWalletPublicKey = publicKey.seedKey,
),
)
if (continuation.isActive) {
@ -102,8 +104,10 @@ class TangemSigner(
}
}
@Suppress("ArrayInDataClass")
data class TangemSignerResponse(
val totalSignedHashes: Int?,
val remainingSignatures: Int?,
val isRing: Boolean,
val signedWalletPublicKey: ByteArray,
)