Updated on 2026-08-14
This commit is contained in:
parent
fa41036fca
commit
de6b0af228
18 changed files with 147 additions and 90 deletions
|
|
@ -1,6 +1,5 @@
|
|||
package com.tangem.tap.domain.model
|
||||
|
||||
import com.tangem.common.extensions.toHexString
|
||||
import com.tangem.domain.common.ScanResponse
|
||||
import com.tangem.domain.common.util.UserWalletId
|
||||
|
||||
|
|
@ -33,23 +32,4 @@ data class UserWallet(
|
|||
|
||||
val isLocked: Boolean
|
||||
get() = scanResponse.card.wallets.isEmpty()
|
||||
}
|
||||
|
||||
/**
|
||||
* !!! Workaround !!!
|
||||
*
|
||||
* Calculate same [UserWalletId] for twins instead
|
||||
*
|
||||
* TODO: Remove after [REDACTED_JIRA]
|
||||
* */
|
||||
fun UserWallet.isTwinnedWith(other: UserWallet): Boolean {
|
||||
if (!scanResponse.isTangemTwins() || !other.scanResponse.isTangemTwins()) return false
|
||||
if (scanResponse.secondTwinPublicKey == null || other.scanResponse.secondTwinPublicKey == null) return false
|
||||
if (other.scanResponse.secondTwinPublicKey == scanResponse.card.wallets.firstOrNull()?.publicKey?.toHexString()) {
|
||||
return true
|
||||
}
|
||||
if (scanResponse.secondTwinPublicKey == other.scanResponse.card.wallets.firstOrNull()?.publicKey?.toHexString()) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
@ -8,7 +8,6 @@ import com.tangem.domain.common.ScanResponse
|
|||
import com.tangem.domain.common.TapWorkarounds.isStart2Coin
|
||||
import com.tangem.domain.common.TwinCardNumber
|
||||
import com.tangem.domain.common.TwinsHelper
|
||||
import com.tangem.domain.common.util.userWalletId
|
||||
import com.tangem.operations.attestation.OnlineCardVerifier
|
||||
import com.tangem.operations.attestation.TangemApi
|
||||
import com.tangem.tap.domain.model.UserWallet
|
||||
|
|
@ -49,16 +48,20 @@ class UserWalletBuilder(
|
|||
}
|
||||
}
|
||||
|
||||
suspend fun build(): UserWallet {
|
||||
suspend fun build(): UserWallet? {
|
||||
return with(scanResponse) {
|
||||
UserWallet(
|
||||
walletId = card.userWalletId,
|
||||
name = userWalletName,
|
||||
artworkUrl = loadArtworkUrl(card.cardId, card.cardPublicKey),
|
||||
cardsInWallet = backupCardsIds.plus(card.cardId),
|
||||
scanResponse = this,
|
||||
isMultiCurrency = isMultiCurrency,
|
||||
)
|
||||
UserWalletIdBuilder.scanResponse(scanResponse)
|
||||
.build()
|
||||
?.let {
|
||||
UserWallet(
|
||||
walletId = it,
|
||||
name = userWalletName,
|
||||
artworkUrl = loadArtworkUrl(card.cardId, card.cardPublicKey),
|
||||
cardsInWallet = backupCardsIds.plus(card.cardId),
|
||||
scanResponse = this,
|
||||
isMultiCurrency = isMultiCurrency,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,70 @@
|
|||
package com.tangem.tap.domain.model.builders
|
||||
|
||||
import com.tangem.common.extensions.calculateSha256
|
||||
import com.tangem.common.extensions.hexToBytes
|
||||
import com.tangem.crypto.Secp256k1
|
||||
import com.tangem.domain.common.CardDTO
|
||||
import com.tangem.domain.common.ProductType
|
||||
import com.tangem.domain.common.ScanResponse
|
||||
import com.tangem.domain.common.TapWorkarounds.isTangemTwins
|
||||
import com.tangem.domain.common.extensions.calculateHmacSha256
|
||||
import com.tangem.domain.common.util.UserWalletId
|
||||
|
||||
class UserWalletIdBuilder private constructor(
|
||||
private val publicKey: ByteArray?,
|
||||
private val pairTwinPublicKey: ByteArray? = null,
|
||||
) {
|
||||
fun build(): UserWalletId? {
|
||||
val seed = if (publicKey != null) {
|
||||
if (pairTwinPublicKey != null) {
|
||||
Secp256k1.sum(publicKey, pairTwinPublicKey)
|
||||
} else {
|
||||
publicKey
|
||||
}
|
||||
} else null
|
||||
|
||||
return seed?.let {
|
||||
UserWalletId(value = calculateUserWalletId(it))
|
||||
}
|
||||
}
|
||||
|
||||
private fun calculateUserWalletId(seed: ByteArray?): ByteArray? {
|
||||
val message = MESSAGE_FOR_WALLET_ID.toByteArray()
|
||||
val keyHash = seed?.calculateSha256()
|
||||
|
||||
return if (keyHash != null) {
|
||||
message.calculateHmacSha256(keyHash)
|
||||
} else null
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val MESSAGE_FOR_WALLET_ID = "UserWalletID"
|
||||
|
||||
@Throws(IllegalArgumentException::class)
|
||||
fun card(card: CardDTO): UserWalletIdBuilder {
|
||||
require(!card.isTangemTwins) {
|
||||
"For twin cards use scanResponse to ID calculation"
|
||||
}
|
||||
|
||||
return UserWalletIdBuilder(findPublicKey(card.wallets))
|
||||
}
|
||||
|
||||
fun scanResponse(scanResponse: ScanResponse): UserWalletIdBuilder {
|
||||
return UserWalletIdBuilder(
|
||||
publicKey = findPublicKey(scanResponse.card.wallets),
|
||||
pairTwinPublicKey = when (scanResponse.productType) {
|
||||
ProductType.Twins -> scanResponse.secondTwinPublicKey?.hexToBytes()
|
||||
ProductType.Note,
|
||||
ProductType.Wallet,
|
||||
ProductType.SaltPay,
|
||||
-> null
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private fun findPublicKey(wallets: List<CardDTO.Wallet>): ByteArray? {
|
||||
return wallets.firstOrNull()
|
||||
?.publicKey
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue