Updated on 2026-08-14
This commit is contained in:
parent
53b89d7ff1
commit
4aa1a23229
3 changed files with 45 additions and 19 deletions
|
|
@ -1,9 +1,6 @@
|
|||
package com.tangem.tap.domain.twins
|
||||
|
||||
import com.tangem.CardSession
|
||||
import com.tangem.CardSessionRunnable
|
||||
import com.tangem.Message
|
||||
import com.tangem.TangemSdkError
|
||||
import com.tangem.*
|
||||
import com.tangem.commands.wallet.CreateWalletResponse
|
||||
import com.tangem.commands.wallet.PurgeWalletCommand
|
||||
import com.tangem.common.CompletionResult
|
||||
|
|
@ -14,10 +11,11 @@ import com.tangem.tap.domain.extensions.getSingleWallet
|
|||
import com.tangem.tasks.CreateWalletTask
|
||||
|
||||
class CreateSecondTwinWalletTask(
|
||||
private val firstPublicKey: String,
|
||||
private val firstCardId: String,
|
||||
private val preparingMessage: Message,
|
||||
private val creatingWalletMessage: Message
|
||||
private val firstPublicKey: String,
|
||||
private val firstCardId: String,
|
||||
private val issuerKeys: KeyPair,
|
||||
private val preparingMessage: Message,
|
||||
private val creatingWalletMessage: Message
|
||||
) : CardSessionRunnable<CreateWalletResponse> {
|
||||
override val requiresPin2 = true
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
package com.tangem.tap.domain.twins
|
||||
|
||||
import android.content.Context
|
||||
import com.squareup.moshi.JsonAdapter
|
||||
import com.squareup.moshi.Types
|
||||
import com.tangem.KeyPair
|
||||
import com.tangem.Message
|
||||
import com.tangem.blockchain.extensions.Result
|
||||
|
|
@ -8,16 +11,22 @@ import com.tangem.common.CompletionResult
|
|||
import com.tangem.common.extensions.hexToBytes
|
||||
import com.tangem.common.extensions.toHexString
|
||||
import com.tangem.crypto.CryptoUtils
|
||||
import com.tangem.tap.common.extensions.readAssetAsString
|
||||
import com.tangem.tap.domain.tasks.ScanNoteResponse
|
||||
import com.tangem.tap.network.createMoshi
|
||||
import com.tangem.tap.tangemSdkManager
|
||||
|
||||
class TwinCardsManager(private val scanNoteResponse: ScanNoteResponse) {
|
||||
class TwinCardsManager(private val scanNoteResponse: ScanNoteResponse, context: Context) {
|
||||
|
||||
private val currentCardId: String = scanNoteResponse.card.cardId
|
||||
|
||||
private var currentCardPublicKey: String? = null
|
||||
private var secondCardPublicKey: String? = null
|
||||
|
||||
private val issuerKeyPair: KeyPair = getIssuerKeys(
|
||||
context, scanNoteResponse.card.issuerPublicKey!!.toHexString()
|
||||
)
|
||||
|
||||
suspend fun createFirstWallet(message: Message): SimpleResult {
|
||||
val response = tangemSdkManager.runTaskAsync(
|
||||
CreateFirstTwinWalletTask(), currentCardId, message
|
||||
|
|
@ -41,6 +50,7 @@ class TwinCardsManager(private val scanNoteResponse: ScanNoteResponse) {
|
|||
val task = CreateSecondTwinWalletTask(
|
||||
firstPublicKey = currentCardPublicKey!!,
|
||||
firstCardId = currentCardId,
|
||||
issuerKeys = issuerKeyPair,
|
||||
preparingMessage = preparingMessage,
|
||||
creatingWalletMessage = creatingWalletMessage
|
||||
)
|
||||
|
|
@ -59,7 +69,7 @@ class TwinCardsManager(private val scanNoteResponse: ScanNoteResponse) {
|
|||
|
||||
suspend fun complete(message: Message): Result<ScanNoteResponse> {
|
||||
val response = tangemSdkManager.runTaskAsync(
|
||||
FinalizeTwinTask(secondCardPublicKey!!.hexToBytes(), issuerKeys),
|
||||
FinalizeTwinTask(secondCardPublicKey!!.hexToBytes(), issuerKeyPair),
|
||||
currentCardId, message
|
||||
)
|
||||
return when (response) {
|
||||
|
|
@ -69,13 +79,6 @@ class TwinCardsManager(private val scanNoteResponse: ScanNoteResponse) {
|
|||
}
|
||||
|
||||
companion object {
|
||||
val issuerKeys = KeyPair(
|
||||
privateKey = "F9F4C50636C9E6FC65F92655BD5C21C85A5F6A34DCD0F1E75FCEA1980FE242F5".hexToBytes(),
|
||||
publicKey = ("048196AA4B410AC44A3B9CCE18E7BE226AEA070ACC83A9CF67540F" +
|
||||
"AC49AF25129F6A538A28AD6341358E3C4F9963064F" +
|
||||
"7E365372A651D374E5C23CDD37FD099BF2").hexToBytes()
|
||||
)
|
||||
|
||||
fun verifyTwinPublicKey(issuerData: ByteArray, cardWalletPublicKey: ByteArray?): Boolean {
|
||||
if (issuerData.size < 65) return false
|
||||
val publicKey = issuerData.sliceArray(0 until 65)
|
||||
|
|
@ -83,5 +86,30 @@ class TwinCardsManager(private val scanNoteResponse: ScanNoteResponse) {
|
|||
return (cardWalletPublicKey != null &&
|
||||
CryptoUtils.verify(cardWalletPublicKey, publicKey, signedKey))
|
||||
}
|
||||
|
||||
private fun getIssuerKeys(context: Context, publicKey: String): KeyPair {
|
||||
val issuer = getIssuers(context).first { it.publicKey == publicKey }
|
||||
return KeyPair(
|
||||
publicKey = issuer.publicKey.hexToBytes(),
|
||||
privateKey = issuer.privateKey.hexToBytes()
|
||||
)
|
||||
}
|
||||
|
||||
private fun getAdapter(): JsonAdapter<List<Issuer>> {
|
||||
return createMoshi().adapter(
|
||||
Types.newParameterizedType(List::class.java, Issuer::class.java)
|
||||
)
|
||||
}
|
||||
|
||||
private fun getIssuers(context: Context): List<Issuer> {
|
||||
val file = context.readAssetAsString("tangem-app-config/issuers")
|
||||
return getAdapter().fromJson(file)!!
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class Issuer(
|
||||
val id: String,
|
||||
val privateKey: String,
|
||||
val publicKey: String,
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue