Updated on 2026-08-14

This commit is contained in:
Tangem 2025-12-19 17:25:04 +05:00
parent 71e4d3a6ed
commit 0594e1b680
23 changed files with 298 additions and 208 deletions

View file

@ -1,9 +1,15 @@
package com.tangem.domain.card.common.visa
import com.tangem.blockchain.blockchains.ethereum.EthereumUtils.toKeccak
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.UnmarshalHelper
import com.tangem.blockchain.common.derivation.DerivationStyle
import com.tangem.common.card.EllipticCurve
import com.tangem.common.card.FirmwareVersion
import com.tangem.common.extensions.toDecompressedPublicKey
import com.tangem.common.extensions.toHexString
import com.tangem.crypto.hdWallet.DerivationPath
import com.tangem.crypto.hdWallet.bip32.ExtendedPublicKey
import com.tangem.domain.models.scan.CardDTO
private const val VISA_BATCH_START = "AE"
@ -11,15 +17,16 @@ private const val VISA_BATCH_START_2 = "FFFC"
object VisaUtilities {
const val tokenId = "tether"
val visaBlockchain = Blockchain.Polygon
val visaDefaultDerivationPath
get() = visaBlockchain.derivationPath(DerivationStyle.V3)
val customDerivationPath = DerivationPath("m/44'/60'/999999'/0/0")
val curve = EllipticCurve.Secp256k1
fun visaDefaultDerivationPath(style: DerivationStyle) = visaBlockchain.derivationPath(style)
fun signWithNonceMessage(nonce: String): String {
return "Tangem Pay wants to sign in with your account. Nonce: $nonce"
}
fun isVisaCard(card: CardDTO): Boolean {
return isVisaCard(card.firmwareVersion.doubleValue, card.batchId)
@ -29,4 +36,26 @@ object VisaUtilities {
return firmwareVersion in FirmwareVersion.visaRange &&
(batchId.startsWith(VISA_BATCH_START) || batchId.startsWith(VISA_BATCH_START_2))
}
// TODO: [REDACTED_TASK_KEY] - Get this public function from Blockchain SDK
fun hashPersonalMessage(message: ByteArray): ByteArray {
val prefix = "\u0019Ethereum Signed Message:\n${message.size}".toByteArray()
return (prefix + message).toKeccak()
}
fun generateAddressFromExtendedKey(extendedPublicKey: ExtendedPublicKey): String {
val derivationData = visaBlockchain.makeAddressesFromExtendedPublicKey(
extendedPublicKey = extendedPublicKey,
cachedIndex = null,
)
return derivationData.address
}
fun unmarshallSignature(signature: ByteArray, hash: ByteArray, extendedPublicKey: ExtendedPublicKey): String {
return UnmarshalHelper.unmarshalSignatureExtended(
signature = signature,
hash = hash,
publicKey = extendedPublicKey.publicKey.toDecompressedPublicKey(),
).asRSVLegacyEVM().toHexString().lowercase()
}
}