Updated on 2026-08-14
This commit is contained in:
parent
e91c59c442
commit
c7b11501e7
5 changed files with 151 additions and 59 deletions
|
|
@ -82,7 +82,7 @@ fun WalletManager?.getAddressData(): WalletDataModel.AddressData? {
|
|||
}
|
||||
|
||||
fun <T> WalletManager.Companion.stub(): T {
|
||||
val wallet = Wallet(Blockchain.Unknown, setOf(), Wallet.PublicKey(byteArrayOf(), null, null), setOf())
|
||||
val wallet = Wallet(Blockchain.Unknown, setOf(), Wallet.PublicKey(byteArrayOf(), null), setOf())
|
||||
return object : WalletManager(wallet) {
|
||||
override val currentHost: String = ""
|
||||
override suspend fun update() {}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.tap.domain.tasks.product
|
||||
|
||||
import com.tangem.blockchain.blockchains.cardano.CardanoUtils
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.common.card.Card
|
||||
|
|
@ -217,7 +218,8 @@ private class ScanWalletProcessor(
|
|||
walletData = session.environment.walletData,
|
||||
primaryCard = primaryCard,
|
||||
)
|
||||
val derivations = collectDerivations(card, config, scanResponse.derivationStyleProvider)
|
||||
val derivations =
|
||||
collectDerivations(card, config, scanResponse.derivationStyleProvider)
|
||||
if (derivations.isEmpty() || !card.settings.isHDWalletAllowed) {
|
||||
callback(CompletionResult.Success(scanResponse))
|
||||
return@launch
|
||||
|
|
@ -242,60 +244,101 @@ private class ScanWalletProcessor(
|
|||
val userTokensRepository = userTokensRepository ?: return emptyList()
|
||||
val blockchainsToDerive = userTokensRepository.loadBlockchainsToDerive(card)
|
||||
.toMutableList()
|
||||
.ifEmpty {
|
||||
mutableListOf(
|
||||
BlockchainNetwork(
|
||||
blockchain = Blockchain.Bitcoin,
|
||||
derivationStyleProvider = derivationStyleProvider,
|
||||
),
|
||||
BlockchainNetwork(
|
||||
blockchain = Blockchain.Ethereum,
|
||||
derivationStyleProvider = derivationStyleProvider,
|
||||
),
|
||||
)
|
||||
}
|
||||
.ifEmpty { getDefaultBlockchains(derivationStyleProvider) }
|
||||
|
||||
if (card.settings.isHDWalletAllowed) {
|
||||
blockchainsToDerive.addAll(
|
||||
listOf(
|
||||
BlockchainNetwork(
|
||||
blockchain = Blockchain.Ethereum,
|
||||
derivationStyleProvider = derivationStyleProvider,
|
||||
),
|
||||
BlockchainNetwork(
|
||||
blockchain = Blockchain.EthereumTestnet,
|
||||
derivationStyleProvider = derivationStyleProvider,
|
||||
),
|
||||
),
|
||||
)
|
||||
blockchainsToDerive += getEthereumBlockchains(derivationStyleProvider)
|
||||
}
|
||||
if (additionalBlockchainsToDerive != null) {
|
||||
blockchainsToDerive.addAll(
|
||||
additionalBlockchainsToDerive.map {
|
||||
BlockchainNetwork(
|
||||
blockchain = it,
|
||||
derivationStyleProvider = derivationStyleProvider,
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
additionalBlockchainsToDerive?.let {
|
||||
blockchainsToDerive += getAdditionalBlockchainToDerive(derivationStyleProvider, it)
|
||||
}
|
||||
|
||||
// we should generate second key for cardano
|
||||
// because cardano address generation for wallet2 requires keys from 2 derivations
|
||||
// https://developers.cardano.org/docs/get-started/cardano-serialization-lib/generating-keys/
|
||||
val secondCardanoNetwork = blockchainsToDerive
|
||||
.find { it.blockchain == Blockchain.Cardano }
|
||||
?.let { getCardanoSecondNetwork(it) }
|
||||
secondCardanoNetwork?.let { blockchainsToDerive.add(it) }
|
||||
|
||||
// pay attention to this
|
||||
if (!card.useOldStyleDerivation) {
|
||||
blockchainsToDerive.removeAll(
|
||||
listOf(
|
||||
Blockchain.BSC, Blockchain.BSCTestnet,
|
||||
Blockchain.Polygon, Blockchain.PolygonTestnet,
|
||||
Blockchain.RSK,
|
||||
Blockchain.Fantom, Blockchain.FantomTestnet,
|
||||
Blockchain.Avalanche, Blockchain.AvalancheTestnet,
|
||||
).map {
|
||||
BlockchainNetwork(
|
||||
blockchain = it,
|
||||
derivationStyleProvider = derivationStyleProvider,
|
||||
)
|
||||
},
|
||||
removeUnnecessaryBlockchains(blockchainsToDerive, derivationStyleProvider)
|
||||
}
|
||||
|
||||
return blockchainsToDerive.distinct()
|
||||
}
|
||||
|
||||
private fun getDefaultBlockchains(
|
||||
derivationStyleProvider: DerivationStyleProvider,
|
||||
): MutableList<BlockchainNetwork> {
|
||||
return mutableListOf(
|
||||
BlockchainNetwork(
|
||||
blockchain = Blockchain.Bitcoin,
|
||||
derivationStyleProvider = derivationStyleProvider,
|
||||
),
|
||||
BlockchainNetwork(
|
||||
blockchain = Blockchain.Ethereum,
|
||||
derivationStyleProvider = derivationStyleProvider,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun getEthereumBlockchains(derivationStyleProvider: DerivationStyleProvider): List<BlockchainNetwork> {
|
||||
return listOf(
|
||||
BlockchainNetwork(
|
||||
blockchain = Blockchain.Ethereum,
|
||||
derivationStyleProvider = derivationStyleProvider,
|
||||
),
|
||||
BlockchainNetwork(
|
||||
blockchain = Blockchain.EthereumTestnet,
|
||||
derivationStyleProvider = derivationStyleProvider,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun getAdditionalBlockchainToDerive(
|
||||
derivationStyleProvider: DerivationStyleProvider,
|
||||
collection: Collection<Blockchain>,
|
||||
): List<BlockchainNetwork> {
|
||||
return collection.map {
|
||||
BlockchainNetwork(
|
||||
blockchain = it,
|
||||
derivationStyleProvider = derivationStyleProvider,
|
||||
)
|
||||
}
|
||||
return blockchainsToDerive.distinct()
|
||||
}
|
||||
|
||||
private fun getCardanoSecondNetwork(cardanoBlockchainNetwork: BlockchainNetwork): BlockchainNetwork? {
|
||||
val cardanoStandardDerivation = cardanoBlockchainNetwork.derivationPath?.let { DerivationPath(it) }
|
||||
?: return null
|
||||
val cardanoPatchedDerivation = CardanoUtils.extendedDerivationPath(cardanoStandardDerivation)
|
||||
return BlockchainNetwork(
|
||||
blockchain = Blockchain.Cardano,
|
||||
derivationPath = cardanoPatchedDerivation.rawPath,
|
||||
tokens = emptyList(),
|
||||
)
|
||||
}
|
||||
|
||||
private fun removeUnnecessaryBlockchains(
|
||||
blockchainsToDerive: MutableList<BlockchainNetwork>,
|
||||
derivationStyleProvider: DerivationStyleProvider,
|
||||
) {
|
||||
blockchainsToDerive.removeAll(
|
||||
listOf(
|
||||
Blockchain.BSC, Blockchain.BSCTestnet,
|
||||
Blockchain.Polygon, Blockchain.PolygonTestnet,
|
||||
Blockchain.RSK,
|
||||
Blockchain.Fantom, Blockchain.FantomTestnet,
|
||||
Blockchain.Avalanche, Blockchain.AvalancheTestnet,
|
||||
).map {
|
||||
BlockchainNetwork(
|
||||
blockchain = it,
|
||||
derivationStyleProvider = derivationStyleProvider,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun collectDerivations(
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ object Wallet2CardConfig : CardConfig {
|
|||
|
||||
/**
|
||||
* Logic to determine primary curve for blockchain in TangemWallet 2.0
|
||||
* Order is important here
|
||||
*/
|
||||
override fun primaryCurve(blockchain: Blockchain): EllipticCurve? {
|
||||
// order is important, new curve is preferred for wallet 2
|
||||
|
|
@ -29,6 +30,10 @@ object Wallet2CardConfig : CardConfig {
|
|||
blockchain.getSupportedCurves().contains(EllipticCurve.Bls12381G2Aug) -> {
|
||||
EllipticCurve.Bls12381G2Aug
|
||||
}
|
||||
// only for support cardano on Wallet2
|
||||
blockchain.getSupportedCurves().contains(EllipticCurve.Ed25519) -> {
|
||||
EllipticCurve.Ed25519
|
||||
}
|
||||
else -> {
|
||||
Timber.e("Unsupported blockchain, curve not found")
|
||||
null
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
package com.tangem.domain.common.extensions
|
||||
|
||||
import com.tangem.blockchain.blockchains.cardano.CardanoUtils
|
||||
import com.tangem.blockchain.common.*
|
||||
import com.tangem.blockchain.common.derivation.DerivationStyle
|
||||
import com.tangem.common.card.EllipticCurve
|
||||
import com.tangem.common.extensions.hexToBytes
|
||||
import com.tangem.common.extensions.toMapKey
|
||||
import com.tangem.crypto.hdWallet.DerivationPath
|
||||
import com.tangem.crypto.hdWallet.bip32.ExtendedPublicKey
|
||||
import com.tangem.domain.common.TapWorkarounds.isTestCard
|
||||
import com.tangem.domain.common.TapWorkarounds.useOldStyleDerivation
|
||||
import com.tangem.domain.common.configs.CardConfig
|
||||
|
|
@ -12,6 +15,7 @@ import com.tangem.domain.common.configs.Wallet2CardConfig
|
|||
import com.tangem.domain.common.util.cardTypesResolver
|
||||
import com.tangem.domain.models.scan.CardDTO
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.blockchain.common.CardanoAddressConfig
|
||||
|
||||
fun WalletManagerFactory.makeWalletManagerForApp(
|
||||
scanResponse: ScanResponse,
|
||||
|
|
@ -45,18 +49,19 @@ fun WalletManagerFactory.makeWalletManagerForApp(
|
|||
}
|
||||
scanResponse.card.settings.isHDWalletAllowed && seedKey != null && derivationParams != null -> {
|
||||
val derivedKeys = scanResponse.derivedKeys[wallet.publicKey.toMapKey()]
|
||||
val derivationPath = when (derivationParams) {
|
||||
is DerivationParams.Default -> blockchain.derivationPath(derivationParams.style)
|
||||
is DerivationParams.Custom -> derivationParams.path
|
||||
}
|
||||
val derivedKey = derivedKeys?.get(derivationPath)
|
||||
?: return null
|
||||
val derivationPath = derivationParams.getPath(blockchain)
|
||||
|
||||
val publicKey = makePublicKey(
|
||||
seedKey = wallet.publicKey,
|
||||
blockchain = blockchain,
|
||||
derivationPath = derivationPath ?: return null,
|
||||
derivedWalletKeys = derivedKeys ?: return null,
|
||||
isWallet2 = scanResponse.cardTypesResolver.isWallet2(),
|
||||
)
|
||||
|
||||
createWalletManager(
|
||||
blockchain = environmentBlockchain,
|
||||
seedKey = wallet.publicKey,
|
||||
derivedKey = derivedKey,
|
||||
derivation = derivationParams,
|
||||
publicKey = publicKey,
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
|
|
@ -69,6 +74,45 @@ fun WalletManagerFactory.makeWalletManagerForApp(
|
|||
}
|
||||
}
|
||||
|
||||
private fun makePublicKey(
|
||||
seedKey: ByteArray,
|
||||
blockchain: Blockchain,
|
||||
derivationPath: DerivationPath,
|
||||
derivedWalletKeys: Map<DerivationPath, ExtendedPublicKey>,
|
||||
isWallet2: Boolean,
|
||||
): Wallet.PublicKey {
|
||||
val derivedKey = derivedWalletKeys[derivationPath] ?: error("No derivation found")
|
||||
|
||||
val derivationKey = Wallet.HDKey(
|
||||
path = derivationPath,
|
||||
extendedPublicKey = derivedKey,
|
||||
)
|
||||
|
||||
// we should generate second key for cardano
|
||||
// because cardano address generation for wallet2 requires keys from 2 derivations
|
||||
// https://developers.cardano.org/docs/get-started/cardano-serialization-lib/generating-keys/
|
||||
if (blockchain == Blockchain.Cardano) {
|
||||
CardanoAddressConfig.useExtendedAddressing = isWallet2
|
||||
|
||||
if (isWallet2) {
|
||||
val extendedDerivationPath = CardanoUtils.extendedDerivationPath(derivationPath)
|
||||
val secondDerivedKey = derivedWalletKeys[extendedDerivationPath] ?: error("No derivation found")
|
||||
|
||||
val secondDerivationKey = Wallet.HDKey(secondDerivedKey, extendedDerivationPath)
|
||||
|
||||
return Wallet.PublicKey(
|
||||
seedKey = seedKey,
|
||||
derivationType = Wallet.PublicKey.DerivationType.Double(derivationKey, secondDerivationKey),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return Wallet.PublicKey(
|
||||
seedKey = seedKey,
|
||||
derivationType = Wallet.PublicKey.DerivationType.Plain(derivationKey),
|
||||
)
|
||||
}
|
||||
|
||||
private fun getDerivationParams(card: CardDTO): DerivationParams? {
|
||||
return if (!card.settings.isHDWalletAllowed) {
|
||||
null
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ okHttp-prettyLogging = "3.1.0"
|
|||
# endregion Other libraries
|
||||
|
||||
# region Tangem
|
||||
tangemBlockchainSdk = "develop-322"
|
||||
tangemBlockchainSdk = "develop-325"
|
||||
#tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds
|
||||
tangemCardSdk = "develop-289"
|
||||
#tangemCardSdk = "0.0.1" # Keep it! - used for local builds
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue