Updated on 2026-08-14
This commit is contained in:
parent
dee402f968
commit
133dd14ec9
25 changed files with 215 additions and 103 deletions
|
|
@ -1 +1 @@
|
|||
Subproject commit fad890b2a0b552be60d124949ca0a3a4d672dac1
|
||||
Subproject commit 8c1c53b73950698d4acfa4d925b8c14bf6f0da63
|
||||
|
|
@ -94,18 +94,20 @@ class TangemSdkManager(private val cardSdkConfigRepository: CardSdkConfigReposit
|
|||
scanResponse: ScanResponse,
|
||||
mnemonic: String,
|
||||
): CompletionResult<CreateProductWalletTaskResponse> {
|
||||
return when (val seedResult = DefaultMnemonic(mnemonic, tangemSdk.wordlist).generateSeed()) {
|
||||
is CompletionResult.Success -> runTaskAsync(
|
||||
CreateProductWalletTask(
|
||||
cardTypesResolver = scanResponse.cardTypesResolver,
|
||||
derivationStyleProvider = scanResponse.derivationStyleProvider,
|
||||
),
|
||||
scanResponse.card.cardId,
|
||||
Message(resources.getString(R.string.initial_message_create_wallet_body)),
|
||||
)
|
||||
|
||||
is CompletionResult.Failure -> CompletionResult.Failure(seedResult.error)
|
||||
val mnemonic = try {
|
||||
DefaultMnemonic(mnemonic, tangemSdk.wordlist)
|
||||
} catch (e: TangemSdkError.MnemonicException) {
|
||||
return CompletionResult.Failure(e)
|
||||
}
|
||||
return runTaskAsync(
|
||||
CreateProductWalletTask(
|
||||
scanResponse.cardTypesResolver,
|
||||
derivationStyleProvider = scanResponse.derivationStyleProvider,
|
||||
mnemonic,
|
||||
),
|
||||
scanResponse.card.cardId,
|
||||
Message(resources.getString(R.string.initial_message_create_wallet_body)),
|
||||
)
|
||||
}
|
||||
|
||||
private fun sendScanResultsToAnalytics(result: CompletionResult<ScanResponse>) {
|
||||
|
|
|
|||
|
|
@ -11,11 +11,13 @@ import com.tangem.common.extensions.ByteArrayKey
|
|||
import com.tangem.common.extensions.guard
|
||||
import com.tangem.common.extensions.toMapKey
|
||||
import com.tangem.common.map
|
||||
import com.tangem.crypto.bip39.Mnemonic
|
||||
import com.tangem.crypto.hdWallet.DerivationPath
|
||||
import com.tangem.domain.common.CardTypesResolver
|
||||
import com.tangem.domain.common.DerivationStyleProvider
|
||||
import com.tangem.domain.common.TapWorkarounds.isTestCard
|
||||
import com.tangem.domain.common.extensions.derivationPath
|
||||
import com.tangem.domain.common.configs.CardConfig
|
||||
import com.tangem.domain.models.scan.CardDTO
|
||||
import com.tangem.domain.models.scan.KeyWalletPublicKey
|
||||
import com.tangem.operations.CommandResponse
|
||||
|
|
@ -58,7 +60,7 @@ private data class CreateWalletResponse(
|
|||
class CreateProductWalletTask(
|
||||
private val cardTypesResolver: CardTypesResolver,
|
||||
private val derivationStyleProvider: DerivationStyleProvider,
|
||||
private val seed: ByteArray? = null,
|
||||
private val mnemonic: Mnemonic? = null,
|
||||
) : CardSessionRunnable<CreateProductWalletTaskResponse> {
|
||||
|
||||
override val allowsRequestAccessCodeFromRepository: Boolean = false
|
||||
|
|
@ -78,7 +80,7 @@ class CreateProductWalletTask(
|
|||
cardTypesResolver.isTangemTwins() ->
|
||||
throw UnsupportedOperationException("Use the TwinCardsManager to create a wallet")
|
||||
|
||||
else -> CreateWalletTangemWallet(seed, derivationStyleProvider)
|
||||
else -> CreateWalletTangemWallet(mnemonic, derivationStyleProvider)
|
||||
}
|
||||
commandProcessor.proceed(cardDto, session) {
|
||||
when (it) {
|
||||
|
|
@ -133,8 +135,11 @@ private class CreateWalletTangemNote(private val cardTypesResolver: CardTypesRes
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses for multiWallet 1st and 2nd
|
||||
*/
|
||||
private class CreateWalletTangemWallet(
|
||||
private val seed: ByteArray?,
|
||||
private val mnemonic: Mnemonic?,
|
||||
private val derivationStyleProvider: DerivationStyleProvider,
|
||||
) : ProductCommandProcessor<CreateProductWalletTaskResponse> {
|
||||
|
||||
|
|
@ -145,8 +150,9 @@ private class CreateWalletTangemWallet(
|
|||
session: CardSession,
|
||||
callback: (result: CompletionResult<CreateProductWalletTaskResponse>) -> Unit,
|
||||
) {
|
||||
val config = CardConfig.createConfig(card)
|
||||
val walletsOnCard = card.wallets.map { it.curve }.toSet()
|
||||
val curves = card.supportedCurves.intersect(CURVES_FOR_WALLETS).subtract(walletsOnCard).toList()
|
||||
val curves = card.supportedCurves.intersect(config.mandatoryCurves.toSet()).subtract(walletsOnCard).toList()
|
||||
|
||||
if (curves.isEmpty()) {
|
||||
val createWalletResponses = card.wallets.map { wallet ->
|
||||
|
|
@ -155,8 +161,7 @@ private class CreateWalletTangemWallet(
|
|||
proceedWithCreatedWallets(card, createWalletResponses, session, callback)
|
||||
return
|
||||
}
|
||||
|
||||
CreateWalletsTask(curves, seed).run(session) { result ->
|
||||
CreateWalletsTask(curves, mnemonic).run(session) { result ->
|
||||
when (result) {
|
||||
is CompletionResult.Success -> {
|
||||
proceedWithCreatedWallets(
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ import com.tangem.common.card.EllipticCurve
|
|||
import com.tangem.common.core.CardSession
|
||||
import com.tangem.common.core.CardSessionRunnable
|
||||
import com.tangem.common.core.TangemSdkError
|
||||
import com.tangem.crypto.bip39.Mnemonic
|
||||
import com.tangem.crypto.hdWallet.masterkey.AnyMasterKeyFactory
|
||||
import com.tangem.operations.CommandResponse
|
||||
import com.tangem.operations.wallet.CreateWalletResponse
|
||||
import com.tangem.operations.wallet.CreateWalletTask
|
||||
|
|
@ -18,7 +20,7 @@ class CreateWalletsResponse(
|
|||
|
||||
class CreateWalletsTask(
|
||||
private val curves: List<EllipticCurve>,
|
||||
private val seed: ByteArray? = null,
|
||||
private val mnemonic: Mnemonic? = null,
|
||||
) : CardSessionRunnable<CreateWalletsResponse> {
|
||||
|
||||
private val createdWalletsResponses = mutableListOf<CreateWalletResponse>()
|
||||
|
|
@ -38,7 +40,10 @@ class CreateWalletsTask(
|
|||
session: CardSession,
|
||||
callback: (result: CompletionResult<CreateWalletsResponse>) -> Unit,
|
||||
) {
|
||||
CreateWalletTask(curve, seed).run(session) { result ->
|
||||
val extendedPrivateKey = mnemonic?.let {
|
||||
AnyMasterKeyFactory(mnemonic = it, passphrase = "").makeMasterKey(curve)
|
||||
}
|
||||
CreateWalletTask(curve, extendedPrivateKey).run(session) { result ->
|
||||
when (result) {
|
||||
is CompletionResult.Success -> {
|
||||
createdWalletsResponses.add(result.data)
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import com.tangem.domain.common.TapWorkarounds.isStart2Coin
|
|||
import com.tangem.domain.common.TapWorkarounds.isTangemTwins
|
||||
import com.tangem.domain.common.TapWorkarounds.useOldStyleDerivation
|
||||
import com.tangem.domain.common.TwinsHelper
|
||||
import com.tangem.domain.common.extensions.getPrimaryCurve
|
||||
import com.tangem.domain.common.configs.CardConfig
|
||||
import com.tangem.domain.common.util.derivationStyleProvider
|
||||
import com.tangem.domain.models.scan.CardDTO
|
||||
import com.tangem.domain.models.scan.ProductType
|
||||
|
|
@ -209,6 +209,7 @@ private class ScanWalletProcessor(
|
|||
callback: (result: CompletionResult<ScanResponse>) -> Unit,
|
||||
) {
|
||||
val productType = ProductType.Wallet
|
||||
val config = CardConfig.createConfig(card)
|
||||
scope.launch {
|
||||
val scanResponse = ScanResponse(
|
||||
card = card,
|
||||
|
|
@ -216,7 +217,7 @@ private class ScanWalletProcessor(
|
|||
walletData = session.environment.walletData,
|
||||
primaryCard = primaryCard,
|
||||
)
|
||||
val derivations = collectDerivations(card, scanResponse.derivationStyleProvider)
|
||||
val derivations = collectDerivations(card, config, scanResponse.derivationStyleProvider)
|
||||
if (derivations.isEmpty() || !card.settings.isHDWalletAllowed) {
|
||||
callback(CompletionResult.Success(scanResponse))
|
||||
return@launch
|
||||
|
|
@ -299,13 +300,14 @@ private class ScanWalletProcessor(
|
|||
|
||||
private suspend fun collectDerivations(
|
||||
card: CardDTO,
|
||||
config: CardConfig,
|
||||
derivationStyleProvider: DerivationStyleProvider,
|
||||
): Map<ByteArrayKey, List<DerivationPath>> {
|
||||
val blockchains = getBlockchainsToDerive(card, derivationStyleProvider)
|
||||
val derivations = mutableMapOf<ByteArrayKey, List<DerivationPath>>()
|
||||
|
||||
blockchains.forEach { blockchain ->
|
||||
val curve = blockchain.blockchain.getPrimaryCurve()
|
||||
val curve = config.primaryCurve(blockchain.blockchain)
|
||||
val wallet = card.wallets.firstOrNull { it.curve == curve } ?: return@forEach
|
||||
if (wallet.chainCode == null) return@forEach
|
||||
|
||||
|
|
|
|||
|
|
@ -1,27 +0,0 @@
|
|||
package com.tangem.tap.domain.tokens
|
||||
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.common.card.FirmwareVersion
|
||||
import com.tangem.domain.models.scan.CardDTO
|
||||
|
||||
object CurrenciesRepository {
|
||||
fun getBlockchains(cardFirmware: CardDTO.FirmwareVersion, isTestNet: Boolean = false): List<Blockchain> {
|
||||
val blockchains = if (cardFirmware < FirmwareVersion.MultiWalletAvailable) {
|
||||
Blockchain.secp256k1Blockchains(isTestNet)
|
||||
} else {
|
||||
Blockchain.secp256k1Blockchains(isTestNet) + Blockchain.ed25519OnlyBlockchains(isTestNet)
|
||||
}
|
||||
return excludeUnsupportedBlockchains(blockchains)
|
||||
}
|
||||
|
||||
// Use this list to temporarily exclude a blockchain from the list of tokens.
|
||||
private fun excludeUnsupportedBlockchains(blockchains: List<Blockchain>): List<Blockchain> {
|
||||
return blockchains.toMutableList().apply {
|
||||
removeAll(
|
||||
listOf(
|
||||
// Any blockchain
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@ import com.tangem.common.extensions.guard
|
|||
import com.tangem.common.extensions.toMapKey
|
||||
import com.tangem.common.flatMap
|
||||
import com.tangem.crypto.hdWallet.DerivationPath
|
||||
import com.tangem.domain.common.configs.CardConfig
|
||||
import com.tangem.domain.common.extensions.derivationPath
|
||||
import com.tangem.domain.common.extensions.toNetworkId
|
||||
import com.tangem.domain.common.util.derivationStyleProvider
|
||||
|
|
@ -69,10 +70,11 @@ class DefaultCustomTokenInteractor(
|
|||
currencyList: List<Currency>,
|
||||
onSuccess: suspend (ScanResponse) -> Unit,
|
||||
) {
|
||||
val derivationDataList = listOfNotNull(
|
||||
getDerivations(EllipticCurve.Secp256k1, scanResponse, currencyList),
|
||||
getDerivations(EllipticCurve.Ed25519, scanResponse, currencyList),
|
||||
)
|
||||
val config = CardConfig.createConfig(scanResponse.card)
|
||||
val derivationDataList = currencyList.mapNotNull {
|
||||
val curve = config.primaryCurve(it.blockchain)
|
||||
curve?.let { getDerivations(curve, scanResponse, currencyList) }
|
||||
}
|
||||
|
||||
val derivations = derivationDataList.associate(TokensMiddleware.DerivationData::derivations)
|
||||
if (derivations.isEmpty()) {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import com.tangem.common.extensions.guard
|
|||
import com.tangem.common.extensions.toMapKey
|
||||
import com.tangem.common.flatMap
|
||||
import com.tangem.crypto.hdWallet.DerivationPath
|
||||
import com.tangem.domain.common.configs.CardConfig
|
||||
import com.tangem.domain.common.extensions.derivationPath
|
||||
import com.tangem.domain.common.util.derivationStyleProvider
|
||||
import com.tangem.domain.common.util.supportsHdWallet
|
||||
|
|
@ -134,10 +135,11 @@ internal class DefaultTokensListInteractor(
|
|||
}
|
||||
|
||||
private suspend fun deriveMissingBlockchains(scanResponse: ScanResponse, currencies: List<Currency>) {
|
||||
val derivations = listOfNotNull(
|
||||
getDerivations(EllipticCurve.Secp256k1, scanResponse, currencies),
|
||||
getDerivations(EllipticCurve.Ed25519, scanResponse, currencies),
|
||||
).associate(transform = TokensMiddleware.DerivationData::derivations)
|
||||
val config = CardConfig.createConfig(scanResponse.card)
|
||||
val derivations = currencies.mapNotNull {
|
||||
val curve = config.primaryCurve(it.blockchain)
|
||||
curve?.let { getDerivations(curve, scanResponse, currencies) }
|
||||
}.associate(transform = TokensMiddleware.DerivationData::derivations)
|
||||
|
||||
if (derivations.isEmpty()) {
|
||||
submitAdd(scanResponse, currencies)
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import com.tangem.core.navigation.AppScreen
|
|||
import com.tangem.core.navigation.NavigationAction
|
||||
import com.tangem.crypto.hdWallet.DerivationPath
|
||||
import com.tangem.domain.DomainWrapped
|
||||
import com.tangem.domain.common.configs.CardConfig
|
||||
import com.tangem.domain.common.extensions.derivationPath
|
||||
import com.tangem.domain.common.util.derivationStyleProvider
|
||||
import com.tangem.domain.common.util.hasDerivation
|
||||
|
|
@ -119,10 +120,11 @@ object TokensMiddleware {
|
|||
currencyList: List<Currency>,
|
||||
onSuccess: (ScanResponse) -> Unit,
|
||||
) {
|
||||
val derivationDataList = listOfNotNull(
|
||||
getDerivations(EllipticCurve.Secp256k1, scanResponse, currencyList),
|
||||
getDerivations(EllipticCurve.Ed25519, scanResponse, currencyList),
|
||||
)
|
||||
val config = CardConfig.createConfig(scanResponse.card)
|
||||
val derivationDataList = currencyList.mapNotNull {
|
||||
val curve = config.primaryCurve(it.blockchain)
|
||||
curve?.let { getDerivations(curve, scanResponse, currencyList) }
|
||||
}
|
||||
val derivations = derivationDataList.associate { it.derivations }
|
||||
if (derivations.isEmpty()) {
|
||||
onSuccess(scanResponse)
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import com.tangem.common.extensions.ByteArrayKey
|
|||
import com.tangem.common.extensions.toMapKey
|
||||
import com.tangem.crypto.hdWallet.DerivationPath
|
||||
import com.tangem.domain.common.BlockchainNetwork
|
||||
import com.tangem.domain.common.configs.CardConfig
|
||||
import com.tangem.domain.common.extensions.derivationPath
|
||||
import com.tangem.domain.common.extensions.fromNetworkId
|
||||
import com.tangem.domain.common.util.derivationStyleProvider
|
||||
|
|
@ -94,10 +95,11 @@ class DerivationManagerImpl(
|
|||
onSuccess: (ScanResponse) -> Unit,
|
||||
onFailure: (Exception) -> Unit,
|
||||
) {
|
||||
val derivationDataList = listOfNotNull(
|
||||
getDerivations(EllipticCurve.Secp256k1, scanResponse, currencyList),
|
||||
getDerivations(EllipticCurve.Ed25519, scanResponse, currencyList),
|
||||
)
|
||||
val config = CardConfig.createConfig(scanResponse.card)
|
||||
val derivationDataList = currencyList.mapNotNull {
|
||||
val curve = config.primaryCurve(it.blockchain)
|
||||
curve?.let { getDerivations(curve, scanResponse, currencyList) }
|
||||
}
|
||||
val derivations = derivationDataList.associate { it.derivations }
|
||||
if (derivations.isEmpty()) {
|
||||
onSuccess(scanResponse)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
package com.tangem.domain.common.configs
|
||||
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.common.card.EllipticCurve
|
||||
import com.tangem.common.card.FirmwareVersion
|
||||
import com.tangem.domain.models.scan.CardDTO
|
||||
|
||||
sealed interface CardConfig {
|
||||
|
||||
val mandatoryCurves: List<EllipticCurve>
|
||||
|
||||
fun primaryCurve(blockchain: Blockchain): EllipticCurve?
|
||||
|
||||
companion object {
|
||||
|
||||
fun createConfig(cardDTO: CardDTO): CardConfig {
|
||||
if (cardDTO.firmwareVersion >= FirmwareVersion.Ed25519Slip0010Available) {
|
||||
return Wallet2CardConfig
|
||||
}
|
||||
if (cardDTO.settings.isBackupAllowed && cardDTO.settings.isHDWalletAllowed &&
|
||||
cardDTO.firmwareVersion >= FirmwareVersion.MultiWalletAvailable
|
||||
) {
|
||||
return TangemWalletCardConfig
|
||||
}
|
||||
error("This card is not supported by this configs")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
package com.tangem.domain.common.configs
|
||||
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.common.card.EllipticCurve
|
||||
import timber.log.Timber
|
||||
|
||||
object TangemWalletCardConfig : CardConfig {
|
||||
override val mandatoryCurves: List<EllipticCurve>
|
||||
get() = listOf(
|
||||
EllipticCurve.Secp256k1,
|
||||
EllipticCurve.Ed25519,
|
||||
EllipticCurve.Bip0340,
|
||||
EllipticCurve.Bls12381G2Aug,
|
||||
)
|
||||
|
||||
/**
|
||||
* Old logic to determine primary curve for blockchain in TangemWallet
|
||||
*/
|
||||
override fun primaryCurve(blockchain: Blockchain): EllipticCurve? {
|
||||
return when {
|
||||
blockchain.getSupportedCurves().contains(EllipticCurve.Secp256k1) -> {
|
||||
EllipticCurve.Secp256k1
|
||||
}
|
||||
blockchain.getSupportedCurves().contains(EllipticCurve.Ed25519) -> {
|
||||
EllipticCurve.Ed25519
|
||||
}
|
||||
else -> {
|
||||
Timber.e("Unsupported blockchain, curve not found")
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
package com.tangem.domain.common.configs
|
||||
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.common.card.EllipticCurve
|
||||
import timber.log.Timber
|
||||
|
||||
object Wallet2CardConfig : CardConfig {
|
||||
override val mandatoryCurves: List<EllipticCurve>
|
||||
get() = listOf(
|
||||
EllipticCurve.Secp256k1,
|
||||
EllipticCurve.Ed25519,
|
||||
EllipticCurve.Bip0340,
|
||||
EllipticCurve.Bls12381G2Aug,
|
||||
EllipticCurve.Ed25519Slip0010,
|
||||
)
|
||||
|
||||
/**
|
||||
* Logic to determine primary curve for blockchain in TangemWallet 2.0
|
||||
*/
|
||||
override fun primaryCurve(blockchain: Blockchain): EllipticCurve? {
|
||||
return when {
|
||||
blockchain.getSupportedCurves().contains(EllipticCurve.Secp256k1) -> {
|
||||
EllipticCurve.Secp256k1
|
||||
}
|
||||
blockchain.getSupportedCurves().contains(EllipticCurve.Ed25519Slip0010) -> {
|
||||
EllipticCurve.Ed25519Slip0010
|
||||
}
|
||||
blockchain.getSupportedCurves().contains(EllipticCurve.Bls12381G2Aug) -> {
|
||||
EllipticCurve.Bls12381G2Aug
|
||||
}
|
||||
else -> {
|
||||
Timber.e("Unsupported blockchain, curve not found")
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -71,6 +71,8 @@ fun Blockchain.Companion.fromNetworkId(networkId: String): Blockchain? {
|
|||
"aleph-zero/test" -> Blockchain.AlephZeroTestnet
|
||||
"octaspace" -> Blockchain.OctaSpace
|
||||
"octaspace/test" -> Blockchain.OctaSpaceTestnet
|
||||
"chia" -> Blockchain.Chia
|
||||
"chia/test" -> Blockchain.ChiaTestnet
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
|
@ -141,6 +143,8 @@ fun Blockchain.toNetworkId(): String {
|
|||
Blockchain.AlephZeroTestnet -> "aleph-zero/test"
|
||||
Blockchain.OctaSpace -> "octaspace"
|
||||
Blockchain.OctaSpaceTestnet -> "octaspace/test"
|
||||
Blockchain.Chia -> "chia"
|
||||
Blockchain.ChiaTestnet -> "chia/test"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -185,6 +189,8 @@ fun Blockchain.toCoinId(): String {
|
|||
Blockchain.Telos, Blockchain.TelosTestnet -> "telos"
|
||||
Blockchain.AlephZero, Blockchain.AlephZeroTestnet -> "aleph-zero"
|
||||
Blockchain.OctaSpace, Blockchain.OctaSpaceTestnet -> "octaspace"
|
||||
Blockchain.Chia -> "chia"
|
||||
Blockchain.ChiaTestnet -> "chia/test"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -204,20 +210,6 @@ fun Blockchain.minimalAmount(): BigDecimal {
|
|||
return 1.toBigDecimal().movePointLeft(decimals())
|
||||
}
|
||||
|
||||
fun Blockchain.getPrimaryCurve(): EllipticCurve? {
|
||||
return when {
|
||||
getSupportedCurves().contains(EllipticCurve.Secp256k1) -> {
|
||||
EllipticCurve.Secp256k1
|
||||
}
|
||||
getSupportedCurves().contains(EllipticCurve.Ed25519) -> {
|
||||
EllipticCurve.Ed25519
|
||||
}
|
||||
else -> {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun Blockchain.derivationPath(style: DerivationStyle?): DerivationPath? {
|
||||
if (style == null) return null
|
||||
if (!getSupportedCurves().contains(EllipticCurve.Secp256k1) &&
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ import com.tangem.common.extensions.hexToBytes
|
|||
import com.tangem.common.extensions.toMapKey
|
||||
import com.tangem.domain.common.TapWorkarounds.isTestCard
|
||||
import com.tangem.domain.common.TapWorkarounds.useOldStyleDerivation
|
||||
import com.tangem.domain.common.configs.CardConfig
|
||||
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
|
||||
|
|
@ -16,11 +18,16 @@ fun WalletManagerFactory.makeWalletManagerForApp(
|
|||
derivationParams: DerivationParams?,
|
||||
): WalletManager? {
|
||||
val card = scanResponse.card
|
||||
val cardConfig = CardConfig.createConfig(card)
|
||||
if (card.isTestCard && blockchain.getTestnetVersion() == null) return null
|
||||
val supportedCurves = blockchain.getSupportedCurves()
|
||||
|
||||
val wallets = card.wallets.filter { wallet -> supportedCurves.contains(wallet.curve) }
|
||||
val wallet = selectWallet(wallets) ?: return null
|
||||
val wallet = selectWallet(
|
||||
wallets = wallets,
|
||||
cardConfig = cardConfig,
|
||||
blockchain = blockchain,
|
||||
) ?: return null
|
||||
|
||||
val environmentBlockchain =
|
||||
if (card.isTestCard) blockchain.getTestnetVersion()!! else blockchain
|
||||
|
|
@ -85,10 +92,19 @@ fun WalletManagerFactory.makePrimaryWalletManager(scanResponse: ScanResponse): W
|
|||
)
|
||||
}
|
||||
|
||||
private fun selectWallet(wallets: List<CardDTO.Wallet>): CardDTO.Wallet? {
|
||||
return when (wallets.size) {
|
||||
0 -> null
|
||||
1 -> wallets[0]
|
||||
else -> wallets.firstOrNull { it.curve == EllipticCurve.Secp256k1 } ?: wallets[0]
|
||||
private fun selectWallet(
|
||||
wallets: List<CardDTO.Wallet>,
|
||||
cardConfig: CardConfig,
|
||||
blockchain: Blockchain,
|
||||
): CardDTO.Wallet? {
|
||||
return if (cardConfig is Wallet2CardConfig) {
|
||||
val primaryCurve = cardConfig.primaryCurve(blockchain)
|
||||
wallets.firstOrNull { it.curve == primaryCurve }
|
||||
} else {
|
||||
when (wallets.size) {
|
||||
0 -> null
|
||||
1 -> wallets[0]
|
||||
else -> wallets.firstOrNull { it.curve == EllipticCurve.Secp256k1 } ?: wallets[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -10,6 +10,8 @@ import com.tangem.domain.common.TangemCardTypesResolver
|
|||
import com.tangem.domain.common.TangemDerivationStyleProvider
|
||||
import com.tangem.domain.common.TapWorkarounds.isTangemTwins
|
||||
import com.tangem.domain.common.TapWorkarounds.isTestCard
|
||||
import com.tangem.domain.common.configs.CardConfig
|
||||
import com.tangem.domain.common.configs.Wallet2CardConfig
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
|
||||
val ScanResponse.cardTypesResolver: CardTypesResolver
|
||||
|
|
@ -35,14 +37,22 @@ fun ScanResponse.hasDerivation(blockchain: Blockchain, rawDerivationPath: String
|
|||
|
||||
private fun ScanResponse.hasDerivation(blockchain: Blockchain, derivationPath: DerivationPath): Boolean {
|
||||
val isTestnet = card.isTestCard || blockchain.isTestnet()
|
||||
return when {
|
||||
Blockchain.secp256k1Blockchains(isTestnet).contains(blockchain) -> {
|
||||
hasDerivation(EllipticCurve.Secp256k1, derivationPath)
|
||||
val config = CardConfig.createConfig(card)
|
||||
return if (config is Wallet2CardConfig) {
|
||||
// new logic for wallet2
|
||||
val primaryCurve = config.primaryCurve(blockchain)
|
||||
primaryCurve?.let { hasDerivation(it, derivationPath) } ?: false
|
||||
} else {
|
||||
// leave logic for legacy wallets
|
||||
when {
|
||||
Blockchain.secp256k1Blockchains(isTestnet).contains(blockchain) -> {
|
||||
hasDerivation(EllipticCurve.Secp256k1, derivationPath)
|
||||
}
|
||||
Blockchain.ed25519OnlyBlockchains(isTestnet).contains(blockchain) -> {
|
||||
hasDerivation(EllipticCurve.Ed25519, derivationPath)
|
||||
}
|
||||
else -> false
|
||||
}
|
||||
Blockchain.ed25519OnlyBlockchains(isTestnet).contains(blockchain) -> {
|
||||
hasDerivation(EllipticCurve.Ed25519, derivationPath)
|
||||
}
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ class BlockchainTests {
|
|||
.toMutableList()
|
||||
.apply {
|
||||
remove(Blockchain.Unknown)
|
||||
remove(Blockchain.Optimism)
|
||||
}
|
||||
.map { it to Blockchain.fromNetworkId(it.toNetworkId()) }
|
||||
.mapNotNull { if (it.second == null) it.first else null }
|
||||
|
|
|
|||
|
|
@ -112,4 +112,5 @@ private fun MnemonicErrorResult.mapToError(): SeedPhraseError = when (this) {
|
|||
MnemonicErrorResult.NormalizationFailed -> SeedPhraseError.NormalizationFailed
|
||||
MnemonicErrorResult.UnsupportedLanguage -> SeedPhraseError.UnsupportedLanguage
|
||||
is MnemonicErrorResult.InvalidWords -> SeedPhraseError.InvalidWords(this.words)
|
||||
MnemonicErrorResult.InvalidMnemonic -> SeedPhraseError.InvalidMnemonic
|
||||
}
|
||||
|
|
@ -37,4 +37,5 @@ sealed class SeedPhraseError(
|
|||
object NormalizationFailed : SeedPhraseError(subCode = 5)
|
||||
object UnsupportedLanguage : SeedPhraseError(subCode = 6)
|
||||
data class InvalidWords(val words: Set<String>) : SeedPhraseError(subCode = 7)
|
||||
object InvalidMnemonic : SeedPhraseError(subCode = 8)
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||
# Specifies the JVM arguments used for the daemon process.
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
org.gradle.jvmargs = -Xmx4096m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
||||
org.gradle.jvmargs = -Xmx4096m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
# This option should only be used with decoupled projects. More details, visit
|
||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||
|
|
|
|||
|
|
@ -80,9 +80,9 @@ okHttp-prettyLogging = "3.1.0"
|
|||
# endregion Other libraries
|
||||
|
||||
# region Tangem
|
||||
tangemBlockchainSdk = "develop-306"
|
||||
tangemBlockchainSdk = "develop-312"
|
||||
#tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds
|
||||
tangemCardSdk = "develop-283"
|
||||
tangemCardSdk = "develop-288"
|
||||
#tangemCardSdk = "0.0.1" # Keep it! - used for local builds
|
||||
# endregion Tangem
|
||||
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ repositories {
|
|||
}
|
||||
|
||||
configure<JavaPluginExtension> {
|
||||
sourceCompatibility = JavaVersion.VERSION_11
|
||||
targetCompatibility = JavaVersion.VERSION_11
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
|
|
|||
|
|
@ -47,6 +47,6 @@ private fun Project.configureDetektTask() {
|
|||
}
|
||||
}
|
||||
|
||||
jvmTarget = "11"
|
||||
jvmTarget = "17"
|
||||
}
|
||||
}
|
||||
|
|
@ -7,7 +7,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
|||
internal fun Project.configureKotlinCompilerOptions() {
|
||||
project.tasks.withType<KotlinCompile> {
|
||||
kotlinOptions {
|
||||
jvmTarget = "11"
|
||||
jvmTarget = "17"
|
||||
allWarningsAsErrors = false
|
||||
// this is required to produce a unique META-INF/*.kotlin_module files
|
||||
moduleName = project.path.removePrefix(":").replace(':', '-')
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ internal fun BaseExtension.configureCompileSdk() {
|
|||
|
||||
internal fun BaseExtension.configureCompilerOptions() {
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_11
|
||||
targetCompatibility = JavaVersion.VERSION_11
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue