Updated on 2026-08-14
This commit is contained in:
parent
229a2d7236
commit
e9fac0e50e
10 changed files with 101 additions and 39 deletions
|
|
@ -1,109 +0,0 @@
|
|||
package com.tangem.tap.domain.card
|
||||
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.FeePaidCurrency
|
||||
import com.tangem.blockchain.common.Token
|
||||
import com.tangem.blockchainsdk.utils.ExcludedBlockchains
|
||||
import com.tangem.blockchainsdk.utils.toNetworkId
|
||||
import com.tangem.data.common.currency.CryptoCurrencyFactory
|
||||
import com.tangem.data.common.currency.getNetworkDerivationPath
|
||||
import com.tangem.data.common.currency.getNetworkStandardType
|
||||
import com.tangem.domain.common.util.derivationStyleProvider
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.Network
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal class CryptoCurrenciesMocks(private val scanResponse: ScanResponse) {
|
||||
|
||||
private val factory = CryptoCurrencyFactory(excludedBlockchains = ExcludedBlockchains())
|
||||
|
||||
val cardano by lazy { listOf(createCoin(blockchain = Blockchain.Cardano)) }
|
||||
val chia by lazy { listOf(element = createCoin(Blockchain.Chia)) }
|
||||
val ethereum by lazy { listOf(element = createCoin(Blockchain.Ethereum)) }
|
||||
|
||||
val chiaAndEthereum by lazy {
|
||||
listOf(
|
||||
createCoin(blockchain = Blockchain.Chia),
|
||||
createCoin(blockchain = Blockchain.Ethereum),
|
||||
)
|
||||
}
|
||||
|
||||
val ethereumAndStellar by lazy {
|
||||
listOf(
|
||||
createCoin(blockchain = Blockchain.Ethereum),
|
||||
createCoin(blockchain = Blockchain.Stellar),
|
||||
)
|
||||
}
|
||||
|
||||
val ethereumTokenWithBinanceDerivation by lazy {
|
||||
listOf(
|
||||
createCustomToken(blockchain = Blockchain.Ethereum, derivationBlockchain = Blockchain.Binance),
|
||||
)
|
||||
}
|
||||
|
||||
private fun createCoin(blockchain: Blockchain): CryptoCurrency {
|
||||
val network = Network(
|
||||
id = Network.ID(blockchain.id),
|
||||
backendId = blockchain.toNetworkId(),
|
||||
name = blockchain.fullName,
|
||||
isTestnet = blockchain.isTestnet(),
|
||||
derivationPath = getNetworkDerivationPath(
|
||||
blockchain,
|
||||
extraDerivationPath = null,
|
||||
scanResponse.derivationStyleProvider,
|
||||
),
|
||||
currencySymbol = blockchain.currency,
|
||||
standardType = getNetworkStandardType(blockchain),
|
||||
hasFiatFeeRate = blockchain.feePaidCurrency() !is FeePaidCurrency.FeeResource,
|
||||
canHandleTokens = false,
|
||||
transactionExtrasType = Network.TransactionExtrasType.NONE,
|
||||
)
|
||||
|
||||
return factory.createCoin(network = network)
|
||||
}
|
||||
|
||||
// Impossible to create custom token by CryptoCurrencyFactory because it works with URI under the hood
|
||||
private fun createCustomToken(blockchain: Blockchain, derivationBlockchain: Blockchain): CryptoCurrency {
|
||||
return CryptoCurrency.Token(
|
||||
id = CryptoCurrency.ID(
|
||||
prefix = CryptoCurrency.ID.Prefix.TOKEN_PREFIX,
|
||||
body = CryptoCurrency.ID.Body.NetworkId(blockchain.id),
|
||||
suffix = CryptoCurrency.ID.Suffix.RawID(blockchain.id),
|
||||
),
|
||||
network = Network(
|
||||
id = Network.ID(value = blockchain.id),
|
||||
backendId = "NEVER-MIND",
|
||||
name = blockchain.fullName,
|
||||
currencySymbol = "NEVER-MIND",
|
||||
derivationPath = Network.DerivationPath.Custom(
|
||||
value = derivationBlockchain.derivationPath(
|
||||
scanResponse.derivationStyleProvider.getDerivationStyle(),
|
||||
)!!.rawPath,
|
||||
),
|
||||
isTestnet = false,
|
||||
standardType = Network.StandardType.ERC20,
|
||||
hasFiatFeeRate = true,
|
||||
canHandleTokens = true,
|
||||
transactionExtrasType = Network.TransactionExtrasType.NONE,
|
||||
),
|
||||
name = "NEVER-MIND",
|
||||
symbol = "NEVER-MIND",
|
||||
decimals = 8,
|
||||
iconUrl = null,
|
||||
isCustom = false,
|
||||
contractAddress = "NEVER-MIND",
|
||||
)
|
||||
}
|
||||
|
||||
private fun createToken(blockchain: Blockchain): CryptoCurrency {
|
||||
return factory.createToken(
|
||||
sdkToken = Token(symbol = "NEVER-MIND", contractAddress = "NEVER-MIND", decimals = 8),
|
||||
blockchain = blockchain,
|
||||
extraDerivationPath = null,
|
||||
scanResponse = scanResponse,
|
||||
)!!
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,8 @@ import android.annotation.SuppressLint
|
|||
import com.google.common.truth.Truth
|
||||
import com.tangem.blockchainsdk.utils.ExcludedBlockchains
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.common.test.domain.card.MockScanResponseFactory
|
||||
import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory
|
||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||
import com.tangem.domain.card.ScanCardException
|
||||
import com.tangem.domain.common.configs.GenericCardConfig
|
||||
|
|
@ -40,7 +42,7 @@ internal class DefaultDerivationsRepositoryTest {
|
|||
artworkUrl = "",
|
||||
cardsInWallet = setOf(),
|
||||
isMultiCurrency = false,
|
||||
scanResponse = ScanResponseMockFactory.create(cardConfig = GenericCardConfig(2), derivedKeys = emptyMap()),
|
||||
scanResponse = MockScanResponseFactory.create(cardConfig = GenericCardConfig(2), derivedKeys = emptyMap()),
|
||||
hasBackupError = false,
|
||||
)
|
||||
|
||||
|
|
@ -77,7 +79,7 @@ internal class DefaultDerivationsRepositoryTest {
|
|||
@Test
|
||||
fun `success if currencies is empty`() = runTest {
|
||||
val userWallet = defaultUserWallet.copy(
|
||||
scanResponse = ScanResponseMockFactory.create(cardConfig = MultiWalletCardConfig, derivedKeys = emptyMap()),
|
||||
scanResponse = MockScanResponseFactory.create(cardConfig = MultiWalletCardConfig, derivedKeys = emptyMap()),
|
||||
)
|
||||
coEvery { userWalletsStore.getSyncOrNull(defaultUserWalletId) } returns userWallet
|
||||
|
||||
|
|
@ -94,7 +96,7 @@ internal class DefaultDerivationsRepositoryTest {
|
|||
@Test
|
||||
fun `success if card already has derivations`() = runTest {
|
||||
val userWallet = defaultUserWallet.copy(
|
||||
scanResponse = ScanResponseMockFactory.create(
|
||||
scanResponse = MockScanResponseFactory.create(
|
||||
cardConfig = MultiWalletCardConfig,
|
||||
derivedKeys = DerivedKeysMocks.ethereumDerivedKeys,
|
||||
),
|
||||
|
|
@ -105,7 +107,7 @@ internal class DefaultDerivationsRepositoryTest {
|
|||
runCatching {
|
||||
repository.derivePublicKeys(
|
||||
userWalletId = defaultUserWalletId,
|
||||
currencies = CryptoCurrenciesMocks(userWallet.scanResponse).ethereum,
|
||||
currencies = MockCryptoCurrencyFactory(userWallet.scanResponse).ethereum.let(::listOf),
|
||||
)
|
||||
}
|
||||
.onSuccess { Truth.assertThat(it) }
|
||||
|
|
@ -119,7 +121,7 @@ internal class DefaultDerivationsRepositoryTest {
|
|||
@Test
|
||||
fun `error if tangemSdkManager throws exception`() = runTest {
|
||||
val userWallet = defaultUserWallet.copy(
|
||||
scanResponse = ScanResponseMockFactory.create(cardConfig = MultiWalletCardConfig, derivedKeys = emptyMap()),
|
||||
scanResponse = MockScanResponseFactory.create(cardConfig = MultiWalletCardConfig, derivedKeys = emptyMap()),
|
||||
)
|
||||
coEvery { userWalletsStore.getSyncOrNull(defaultUserWalletId) } returns userWallet
|
||||
coEvery { tangemSdkManager.derivePublicKeys(null, any(), any()) } throws ScanCardException.UserCancelled
|
||||
|
|
@ -127,7 +129,7 @@ internal class DefaultDerivationsRepositoryTest {
|
|||
runCatching {
|
||||
repository.derivePublicKeys(
|
||||
userWalletId = defaultUserWalletId,
|
||||
currencies = CryptoCurrenciesMocks(userWallet.scanResponse).ethereum,
|
||||
currencies = MockCryptoCurrencyFactory(userWallet.scanResponse).ethereum.let(::listOf),
|
||||
)
|
||||
}
|
||||
.onSuccess { error("Should throws exception") }
|
||||
|
|
@ -142,7 +144,7 @@ internal class DefaultDerivationsRepositoryTest {
|
|||
@Test
|
||||
fun `success case`() = runTest {
|
||||
val userWallet = defaultUserWallet.copy(
|
||||
scanResponse = ScanResponseMockFactory.create(cardConfig = MultiWalletCardConfig, derivedKeys = emptyMap()),
|
||||
scanResponse = MockScanResponseFactory.create(cardConfig = MultiWalletCardConfig, derivedKeys = emptyMap()),
|
||||
)
|
||||
coEvery { userWalletsStore.getSyncOrNull(defaultUserWalletId) } returns userWallet
|
||||
coEvery { tangemSdkManager.derivePublicKeys(null, any(), any()) } returns CompletionResult.Success(
|
||||
|
|
@ -153,7 +155,7 @@ internal class DefaultDerivationsRepositoryTest {
|
|||
runCatching {
|
||||
repository.derivePublicKeys(
|
||||
userWalletId = defaultUserWalletId,
|
||||
currencies = CryptoCurrenciesMocks(userWallet.scanResponse).ethereum,
|
||||
currencies = MockCryptoCurrencyFactory(userWallet.scanResponse).ethereum.let(::listOf),
|
||||
)
|
||||
}
|
||||
.onSuccess { Truth.assertThat(it) }
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ import com.tangem.blockchain.common.Blockchain
|
|||
import com.tangem.blockchain.common.derivation.DerivationConfigV2
|
||||
import com.tangem.common.card.EllipticCurve
|
||||
import com.tangem.common.extensions.ByteArrayKey
|
||||
import com.tangem.common.test.domain.card.MockScanResponseFactory
|
||||
import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory
|
||||
import com.tangem.crypto.hdWallet.DerivationPath
|
||||
import com.tangem.domain.common.configs.GenericCardConfig
|
||||
import com.tangem.domain.common.configs.MultiWalletCardConfig
|
||||
|
|
@ -20,7 +22,7 @@ internal class MissedDerivationsFinderTest {
|
|||
|
||||
@Test
|
||||
fun `empty derivations for empty currencies`() {
|
||||
val scanResponse = ScanResponseMockFactory.create(cardConfig = GenericCardConfig(2), derivedKeys = emptyMap())
|
||||
val scanResponse = MockScanResponseFactory.create(cardConfig = GenericCardConfig(2), derivedKeys = emptyMap())
|
||||
val finder = MissedDerivationsFinder(scanResponse)
|
||||
|
||||
val actual = finder.find(emptyList())
|
||||
|
|
@ -31,10 +33,10 @@ internal class MissedDerivationsFinderTest {
|
|||
@Test
|
||||
fun `empty derivations for non supported blockchains`() {
|
||||
// Bls is not supported
|
||||
val scanResponse = ScanResponseMockFactory.create(cardConfig = GenericCardConfig(2), derivedKeys = emptyMap())
|
||||
val scanResponse = MockScanResponseFactory.create(cardConfig = GenericCardConfig(2), derivedKeys = emptyMap())
|
||||
val finder = MissedDerivationsFinder(scanResponse)
|
||||
|
||||
val currencies = CryptoCurrenciesMocks(scanResponse).chia
|
||||
val currencies = MockCryptoCurrencyFactory(scanResponse).chia.let(::listOf)
|
||||
val actual = finder.find(currencies)
|
||||
|
||||
Truth.assertThat(actual).isEmpty()
|
||||
|
|
@ -43,7 +45,7 @@ internal class MissedDerivationsFinderTest {
|
|||
@Test
|
||||
fun `derivations ONLY for supported blockchains`() {
|
||||
// Bls is not supported
|
||||
val scanResponse = ScanResponseMockFactory.create(
|
||||
val scanResponse = MockScanResponseFactory.create(
|
||||
cardConfig = GenericCardConfig(2),
|
||||
derivedKeys = emptyMap(),
|
||||
).let {
|
||||
|
|
@ -55,7 +57,7 @@ internal class MissedDerivationsFinderTest {
|
|||
}
|
||||
val finder = MissedDerivationsFinder(scanResponse)
|
||||
|
||||
val currencies = CryptoCurrenciesMocks(scanResponse).chiaAndEthereum
|
||||
val currencies = MockCryptoCurrencyFactory(scanResponse).chiaAndEthereum
|
||||
val actual = finder.find(currencies)
|
||||
|
||||
Truth.assertThat(actual).containsExactly(
|
||||
|
|
@ -66,10 +68,10 @@ internal class MissedDerivationsFinderTest {
|
|||
|
||||
@Test
|
||||
fun `derivations for custom token`() {
|
||||
val scanResponse = ScanResponseMockFactory.create(cardConfig = MultiWalletCardConfig, derivedKeys = emptyMap())
|
||||
val scanResponse = MockScanResponseFactory.create(cardConfig = MultiWalletCardConfig, derivedKeys = emptyMap())
|
||||
val finder = MissedDerivationsFinder(scanResponse)
|
||||
|
||||
val currencies = CryptoCurrenciesMocks(scanResponse).ethereumTokenWithBinanceDerivation
|
||||
val currencies = MockCryptoCurrencyFactory(scanResponse).ethereumTokenWithBinanceDerivation
|
||||
val actual = finder.find(currencies)
|
||||
|
||||
Truth.assertThat(actual).containsExactly(
|
||||
|
|
@ -83,10 +85,10 @@ internal class MissedDerivationsFinderTest {
|
|||
|
||||
@Test
|
||||
fun `derivations for cardano`() {
|
||||
val scanResponse = ScanResponseMockFactory.create(cardConfig = MultiWalletCardConfig, derivedKeys = emptyMap())
|
||||
val scanResponse = MockScanResponseFactory.create(cardConfig = MultiWalletCardConfig, derivedKeys = emptyMap())
|
||||
val finder = MissedDerivationsFinder(scanResponse)
|
||||
|
||||
val currencies = CryptoCurrenciesMocks(scanResponse).cardano
|
||||
val currencies = MockCryptoCurrencyFactory(scanResponse).cardano.let(::listOf)
|
||||
val actual = finder.find(currencies)
|
||||
|
||||
Truth.assertThat(actual).containsExactly(
|
||||
|
|
@ -105,13 +107,13 @@ internal class MissedDerivationsFinderTest {
|
|||
|
||||
@Test
|
||||
fun `empty derivations for already derived currencies`() {
|
||||
val scanResponse = ScanResponseMockFactory.create(
|
||||
val scanResponse = MockScanResponseFactory.create(
|
||||
cardConfig = Wallet2CardConfig,
|
||||
derivedKeys = DerivedKeysMocks.ethereumDerivedKeys,
|
||||
)
|
||||
val finder = MissedDerivationsFinder(scanResponse)
|
||||
|
||||
val currencies = CryptoCurrenciesMocks(scanResponse).ethereum
|
||||
val currencies = MockCryptoCurrencyFactory(scanResponse).ethereum.let(::listOf)
|
||||
val actual = finder.find(currencies)
|
||||
|
||||
Truth.assertThat(actual).isEmpty()
|
||||
|
|
@ -119,13 +121,13 @@ internal class MissedDerivationsFinderTest {
|
|||
|
||||
@Test
|
||||
fun `derivations ONLY for never derived currencies`() {
|
||||
val scanResponse = ScanResponseMockFactory.create(
|
||||
val scanResponse = MockScanResponseFactory.create(
|
||||
cardConfig = MultiWalletCardConfig,
|
||||
derivedKeys = DerivedKeysMocks.ethereumDerivedKeys,
|
||||
)
|
||||
val finder = MissedDerivationsFinder(scanResponse)
|
||||
|
||||
val currencies = CryptoCurrenciesMocks(scanResponse).ethereumAndStellar
|
||||
val currencies = MockCryptoCurrencyFactory(scanResponse).ethereumAndStellar
|
||||
val actual = finder.find(currencies)
|
||||
|
||||
Truth.assertThat(actual).containsExactly(
|
||||
|
|
|
|||
|
|
@ -1,107 +0,0 @@
|
|||
package com.tangem.tap.domain.card
|
||||
|
||||
import com.tangem.common.card.CardWallet
|
||||
import com.tangem.common.card.FirmwareVersion
|
||||
import com.tangem.domain.common.configs.*
|
||||
import com.tangem.domain.models.scan.CardDTO
|
||||
import com.tangem.domain.models.scan.KeyWalletPublicKey
|
||||
import com.tangem.domain.models.scan.ProductType
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.operations.attestation.Attestation
|
||||
import com.tangem.operations.derivation.ExtendedPublicKeysMap
|
||||
import java.util.Date
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
object ScanResponseMockFactory {
|
||||
|
||||
private val genericFirmwareVersion = CardDTO.FirmwareVersion(
|
||||
major = 3,
|
||||
minor = 29,
|
||||
patch = 0,
|
||||
type = FirmwareVersion.FirmwareType.Release,
|
||||
)
|
||||
|
||||
private val walletFirmwareVersion = CardDTO.FirmwareVersion(
|
||||
major = 4,
|
||||
minor = 0,
|
||||
patch = 0,
|
||||
type = FirmwareVersion.FirmwareType.Release,
|
||||
)
|
||||
|
||||
private val wallet2FirmwareVersion = CardDTO.FirmwareVersion(
|
||||
major = 6,
|
||||
minor = 33,
|
||||
patch = 0,
|
||||
type = FirmwareVersion.FirmwareType.Release,
|
||||
)
|
||||
|
||||
fun create(cardConfig: CardConfig, derivedKeys: Map<KeyWalletPublicKey, ExtendedPublicKeysMap>): ScanResponse {
|
||||
return ScanResponse(
|
||||
card = CardDTO(
|
||||
cardId = "NEVER-MIND",
|
||||
batchId = "NEVER-MIND",
|
||||
cardPublicKey = ByteArray(0),
|
||||
firmwareVersion = when (cardConfig) {
|
||||
is GenericCardConfig -> genericFirmwareVersion
|
||||
MultiWalletCardConfig -> walletFirmwareVersion
|
||||
Wallet2CardConfig -> wallet2FirmwareVersion
|
||||
EdSingleCurrencyCardConfig -> genericFirmwareVersion
|
||||
},
|
||||
manufacturer = CardDTO.Manufacturer(name = "NEVER-MIND", manufactureDate = Date(), signature = null),
|
||||
issuer = CardDTO.Issuer(name = "NEVER-MIND", publicKey = ByteArray(0)),
|
||||
settings = CardDTO.Settings(
|
||||
securityDelay = 0,
|
||||
maxWalletsCount = 0,
|
||||
isSettingAccessCodeAllowed = false,
|
||||
isSettingPasscodeAllowed = false,
|
||||
isResettingUserCodesAllowed = false,
|
||||
isLinkedTerminalEnabled = false,
|
||||
isBackupAllowed = cardConfig is MultiWalletCardConfig,
|
||||
supportedEncryptionModes = listOf(),
|
||||
isFilesAllowed = true,
|
||||
isHDWalletAllowed = cardConfig is MultiWalletCardConfig,
|
||||
isKeysImportAllowed = true,
|
||||
),
|
||||
userSettings = null,
|
||||
linkedTerminalStatus = CardDTO.LinkedTerminalStatus.Current,
|
||||
isAccessCodeSet = false,
|
||||
isPasscodeSet = null,
|
||||
supportedCurves = listOf(),
|
||||
wallets = cardConfig.mandatoryCurves.map {
|
||||
CardDTO.Wallet(
|
||||
CardWallet(
|
||||
publicKey = it.name.toByteArray(), // IMPORTANT: public key must equal to curve name
|
||||
chainCode = null,
|
||||
curve = it,
|
||||
settings = createSettings(),
|
||||
totalSignedHashes = null,
|
||||
remainingSignatures = null,
|
||||
index = 0,
|
||||
isImported = true,
|
||||
hasBackup = true,
|
||||
derivedKeys = mapOf(),
|
||||
),
|
||||
)
|
||||
},
|
||||
attestation = Attestation(
|
||||
cardKeyAttestation = Attestation.Status.Skipped,
|
||||
walletKeysAttestation = Attestation.Status.Skipped,
|
||||
firmwareAttestation = Attestation.Status.Skipped,
|
||||
cardUniquenessAttestation = Attestation.Status.Skipped,
|
||||
),
|
||||
backupStatus = null,
|
||||
),
|
||||
productType = ProductType.Wallet2,
|
||||
walletData = null,
|
||||
derivedKeys = derivedKeys,
|
||||
)
|
||||
}
|
||||
|
||||
private fun createSettings(): CardWallet.Settings {
|
||||
val constructor = CardWallet.Settings::class.java.declaredConstructors[0]
|
||||
constructor.isAccessible = true
|
||||
return constructor.newInstance(false) as CardWallet.Settings
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
package com.tangem.tap.domain.userWalletList.implementation
|
||||
|
||||
import com.google.common.truth.Truth
|
||||
import com.tangem.common.test.domain.card.MockScanResponseFactory
|
||||
import com.tangem.domain.common.configs.GenericCardConfig
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.tap.domain.card.ScanResponseMockFactory
|
||||
import io.mockk.mockk
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
|
@ -198,7 +198,7 @@ internal class BiometricUserWalletsListManagerTest(private val model: Model) {
|
|||
cardsInWallet = emptySet(),
|
||||
isMultiCurrency = true,
|
||||
hasBackupError = false,
|
||||
scanResponse = ScanResponseMockFactory.create(
|
||||
scanResponse = MockScanResponseFactory.create(
|
||||
cardConfig = GenericCardConfig(maxWalletCount = 1),
|
||||
derivedKeys = emptyMap(),
|
||||
).let {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue