Updated on 2026-08-14

This commit is contained in:
Tangem 2025-02-25 17:17:19 +05:00
parent 6d7ae39ba2
commit a09aae7e41
23 changed files with 337 additions and 87 deletions

View file

@ -7,6 +7,8 @@ import com.tangem.blockchain.common.Wallet
import com.tangem.common.CompletionResult
import com.tangem.domain.card.models.TwinKey
import com.tangem.domain.models.scan.isRing
import com.tangem.operations.sign.SignData
import com.tangem.tap.domain.tasks.MultiSignHashTask
import com.tangem.tap.domain.tasks.SignHashesTask
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlin.coroutines.resume
@ -64,6 +66,40 @@ class TangemSigner(
is CompletionResult.Failure -> CompletionResult.Failure(result.error)
}
}
override suspend fun multiSign(
dataToSign: List<SignData>,
publicKey: Wallet.PublicKey,
): CompletionResult<Map<ByteArray, ByteArray>> {
return suspendCancellableCoroutine { continuation ->
val task = MultiSignHashTask(dataToSign, publicKey, twinKey?.getPairKey(publicKey.seedKey))
tangemSdk.startSessionWithRunnable(
runnable = task,
cardId = cardId,
initialMessage = initialMessage,
) { result ->
when (result) {
is CompletionResult.Success -> {
signerCallback(
TangemSignerResponse(
totalSignedHashes = result.data.totalSignedHashes,
remainingSignatures = result.data.remainingSignatures,
isRing = result.data.batchId?.let(::isRing) ?: false,
),
)
if (continuation.isActive) {
continuation.resume(CompletionResult.Success(result.data.signatures))
}
}
is CompletionResult.Failure ->
if (continuation.isActive) {
continuation.resume(CompletionResult.Failure(result.error))
}
}
}
}
}
}
data class TangemSignerResponse(

View file

@ -0,0 +1,80 @@
package com.tangem.tap.domain.tasks
import com.tangem.blockchain.common.Wallet
import com.tangem.common.CompletionResult
import com.tangem.common.core.CardSession
import com.tangem.common.core.CardSessionRunnable
import com.tangem.common.core.CompletionCallback
import com.tangem.common.core.TangemSdkError
import com.tangem.operations.CommandResponse
import com.tangem.operations.sign.MultipleSignCommand
import com.tangem.operations.sign.SignData
class TangemMultiSignHashResponse(
val signatures: Map<ByteArray, ByteArray>,
val totalSignedHashes: Int?,
val remainingSignatures: Int?,
val batchId: String?,
) : CommandResponse
class MultiSignHashTask(
private val dataToSign: List<SignData>,
private val publicKey: Wallet.PublicKey,
private val pairWalletPublicKey: ByteArray?,
) : CardSessionRunnable<TangemMultiSignHashResponse> {
override fun run(session: CardSession, callback: CompletionCallback<TangemMultiSignHashResponse>) {
MultipleSignCommand(dataToSign, publicKey.seedKey).run(session) { response ->
when (response) {
is CompletionResult.Success -> {
val card = session.environment.card
callback(
CompletionResult.Success(
TangemMultiSignHashResponse(
signatures = response.data.associate { it.walletPublicKey to it.signature },
totalSignedHashes = response.data.last().totalSignedHashes,
remainingSignatures = card?.wallet(publicKey.seedKey)?.remainingSignatures,
batchId = card?.batchId,
),
),
)
}
is CompletionResult.Failure -> {
when {
response.error is TangemSdkError.WalletNotFound && pairWalletPublicKey != null -> {
sign(session, pairWalletPublicKey, callback)
}
else -> callback(CompletionResult.Failure(response.error))
}
}
}
}
}
private fun sign(
session: CardSession,
publicKey: ByteArray,
callback: CompletionCallback<TangemMultiSignHashResponse>,
) {
MultipleSignCommand(dataToSign, publicKey).run(session) { response ->
when (response) {
is CompletionResult.Success -> {
val card = session.environment.card
callback(
CompletionResult.Success(
TangemMultiSignHashResponse(
signatures = response.data.associate { it.walletPublicKey to it.signature },
totalSignedHashes = response.data.last().totalSignedHashes,
remainingSignatures = card?.wallet(publicKey)?.remainingSignatures,
batchId = card?.batchId,
),
),
)
}
is CompletionResult.Failure -> {
callback(CompletionResult.Failure(response.error))
}
}
}
}
}