Updated on 2026-08-14
This commit is contained in:
parent
b58be5612e
commit
8966e28e29
55 changed files with 572 additions and 192 deletions
|
|
@ -55,8 +55,7 @@ class MockCryptoCurrencyFactory(private val userWallet: UserWallet.Cold = defaul
|
|||
)
|
||||
|
||||
val network = Network(
|
||||
id = Network.ID(blockchain.id, derivationPath),
|
||||
backendId = blockchain.toNetworkId(),
|
||||
id = Network.ID(value = blockchain.toNetworkId(), derivationPath = derivationPath),
|
||||
name = blockchain.fullName,
|
||||
isTestnet = blockchain.isTestnet(),
|
||||
derivationPath = derivationPath,
|
||||
|
|
@ -85,12 +84,11 @@ class MockCryptoCurrencyFactory(private val userWallet: UserWallet.Cold = defaul
|
|||
return CryptoCurrency.Token(
|
||||
id = CryptoCurrency.ID(
|
||||
prefix = CryptoCurrency.ID.Prefix.TOKEN_PREFIX,
|
||||
body = CryptoCurrency.ID.Body.NetworkId(blockchain.id),
|
||||
body = CryptoCurrency.ID.Body.NetworkId(blockchain.toNetworkId()),
|
||||
suffix = CryptoCurrency.ID.Suffix.RawID(blockchain.id),
|
||||
),
|
||||
network = Network(
|
||||
id = Network.ID(value = blockchain.id, derivationPath),
|
||||
backendId = "NEVER-MIND",
|
||||
id = Network.ID(value = blockchain.toNetworkId(), derivationPath = derivationPath),
|
||||
name = blockchain.fullName,
|
||||
currencySymbol = "NEVER-MIND",
|
||||
derivationPath = derivationPath,
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import com.tangem.datasource.local.preferences.PreferencesKeys.IS_WALLET_SWAP_PR
|
|||
import com.tangem.datasource.local.preferences.PreferencesKeys.SHOULD_SHOW_RING_PROMO_KEY
|
||||
import com.tangem.datasource.local.preferences.utils.CleanupKeyMigration
|
||||
import com.tangem.datasource.local.preferences.utils.SharedPreferencesKeyMigration
|
||||
import com.tangem.datasource.local.preferences.utils.SwapCurrencyIdMigration
|
||||
import com.tangem.utils.coroutines.AppCoroutineScope
|
||||
import com.tangem.utils.logging.TangemLogger
|
||||
|
||||
|
|
@ -80,6 +81,7 @@ internal object PreferencesDataStore {
|
|||
legacyKeyName = LEGACY_DEFAULT_KEY_NAME,
|
||||
keyName = PreferencesKeys.BALANCE_HIDING_SETTINGS_KEY.name,
|
||||
),
|
||||
SwapCurrencyIdMigration(),
|
||||
CleanupKeyMigration(key = APP_LOGS_KEY),
|
||||
CleanupKeyMigration(key = IS_WALLET_SWAP_PROMO_OKX_SHOW_KEY),
|
||||
CleanupKeyMigration(key = IS_TOKEN_SWAP_PROMO_OKX_SHOW_KEY),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,151 @@
|
|||
package com.tangem.datasource.local.preferences.utils
|
||||
|
||||
import androidx.datastore.core.DataMigration
|
||||
import androidx.datastore.preferences.core.Preferences
|
||||
import com.tangem.datasource.local.preferences.PreferencesKeys
|
||||
|
||||
/**
|
||||
* Migrates cached CryptoCurrency.ID strings from old blockchain.id format to new networkId format.
|
||||
*
|
||||
* After refactoring, Network.rawId stores backendId values (e.g. "ethereum") instead of
|
||||
* blockchain.id values (e.g. "ETH"). CryptoCurrency.ID body contains this value, so cached IDs
|
||||
* like "coin⟨ETH⟩ethereum" must become "coin⟨ethereum⟩ethereum".
|
||||
*
|
||||
* Affected DataStore keys: [PreferencesKeys.SWAP_TRANSACTIONS_KEY],
|
||||
* [PreferencesKeys.LAST_SWAPPED_CRYPTOCURRENCY_ID_KEY].
|
||||
*/
|
||||
internal class SwapCurrencyIdMigration : DataMigration<Preferences> {
|
||||
|
||||
override suspend fun shouldMigrate(currentData: Preferences): Boolean {
|
||||
return currentData.contains(PreferencesKeys.SWAP_TRANSACTIONS_KEY) ||
|
||||
currentData.contains(PreferencesKeys.LAST_SWAPPED_CRYPTOCURRENCY_ID_KEY)
|
||||
}
|
||||
|
||||
override suspend fun migrate(currentData: Preferences): Preferences {
|
||||
val mutablePrefs = currentData.toMutablePreferences()
|
||||
|
||||
currentData[PreferencesKeys.SWAP_TRANSACTIONS_KEY]?.let { json ->
|
||||
mutablePrefs[PreferencesKeys.SWAP_TRANSACTIONS_KEY] = migrateJson(json)
|
||||
}
|
||||
|
||||
currentData[PreferencesKeys.LAST_SWAPPED_CRYPTOCURRENCY_ID_KEY]?.let { json ->
|
||||
mutablePrefs[PreferencesKeys.LAST_SWAPPED_CRYPTOCURRENCY_ID_KEY] = migrateJson(json)
|
||||
}
|
||||
|
||||
return mutablePrefs.toPreferences()
|
||||
}
|
||||
|
||||
override suspend fun cleanUp() {
|
||||
// nothing to clean up
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces old blockchain.id values with networkId values inside CryptoCurrency.ID strings
|
||||
* found anywhere in the JSON. Works by finding all `⟨oldId⟩` and `⟨oldId→` patterns and
|
||||
* replacing the old ID with the new one.
|
||||
*/
|
||||
private fun migrateJson(json: String): String {
|
||||
var result = json
|
||||
|
||||
for ((oldId, newId) in BLOCKCHAIN_ID_TO_NETWORK_ID) {
|
||||
// Body without derivation path: ⟨oldId⟩ → ⟨newId⟩
|
||||
result = result.replace("$BODY_START$oldId$BODY_END", "$BODY_START$newId$BODY_END")
|
||||
// Body with derivation path: ⟨oldId→ → ⟨newId→
|
||||
result = result.replace(
|
||||
"$BODY_START$oldId$DERIVATION_DELIMITER",
|
||||
"$BODY_START$newId$DERIVATION_DELIMITER",
|
||||
)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val BODY_START = '\u27E8' // ⟨
|
||||
const val BODY_END = '\u27E9' // ⟩
|
||||
const val DERIVATION_DELIMITER = '\u2192' // →
|
||||
|
||||
/** Mapping of old blockchain.id → new networkId (only entries where values differ). */
|
||||
val BLOCKCHAIN_ID_TO_NETWORK_ID = mapOf(
|
||||
"ARBITRUM-ONE" to "arbitrum-one",
|
||||
"ARBITRUM/test" to "arbitrum-one/test",
|
||||
"AVALANCHE" to "avalanche",
|
||||
"AVALANCHE/test" to "avalanche/test",
|
||||
"BINANCE" to "binancecoin",
|
||||
"BINANCE/test" to "binancecoin/test",
|
||||
"BSC" to "binance-smart-chain",
|
||||
"BSC/test" to "binance-smart-chain/test",
|
||||
"BTC" to "bitcoin",
|
||||
"BTC/test" to "bitcoin/test",
|
||||
"BCH" to "bitcoin-cash",
|
||||
"BCH/test" to "bitcoin-cash/test",
|
||||
"CARDANO-S" to "cardano",
|
||||
"DOGE" to "dogecoin",
|
||||
"DUC" to "ducatus",
|
||||
"ETH" to "ethereum",
|
||||
"ETH/test" to "ethereum/test",
|
||||
"ETC" to "ethereum-classic",
|
||||
"ETC/test" to "ethereum-classic/test",
|
||||
"ETH-Pow" to "ethereum-pow-iou",
|
||||
"ETH-Pow/test" to "ethereum-pow-iou/test",
|
||||
"FTM" to "fantom",
|
||||
"FTM/test" to "fantom/test",
|
||||
"GNO" to "xdai",
|
||||
"KAS" to "kaspa",
|
||||
"KAS/test" to "kaspa/test",
|
||||
"KAVA" to "kava",
|
||||
"KAVA/test" to "kava/test",
|
||||
"Kusama" to "kusama",
|
||||
"LTC" to "litecoin",
|
||||
"NEAR" to "near-protocol",
|
||||
"NEAR/test" to "near-protocol/test",
|
||||
"NEXA" to "nexa",
|
||||
"NEXA/test" to "nexa/test",
|
||||
"OPTIMISM" to "optimistic-ethereum",
|
||||
"Polkadot" to "polkadot",
|
||||
"POLYGON" to "polygon-pos",
|
||||
"POLYGON/test" to "polygon-pos/test",
|
||||
"RSK" to "rootstock",
|
||||
"SOLANA" to "solana",
|
||||
"SOLANA/test" to "solana/test",
|
||||
"TELOS" to "telos",
|
||||
"TELOS/test" to "telos/test",
|
||||
"The-Open-Network" to "the-open-network",
|
||||
"The-Open-Network/test" to "the-open-network/test",
|
||||
"TRON" to "tron",
|
||||
"TRON/test" to "tron/test",
|
||||
"XLM" to "stellar",
|
||||
"XLM/test" to "stellar/test",
|
||||
"XRP" to "xrp",
|
||||
"XTZ" to "tezos",
|
||||
"DASH" to "dash",
|
||||
"xdc" to "xdc-network",
|
||||
"xdc/test" to "xdc-network/test",
|
||||
"hedera" to "hedera-hashgraph",
|
||||
"hedera/test" to "hedera-hashgraph/test",
|
||||
"areon" to "areon-network",
|
||||
"areon/test" to "areon-network/test",
|
||||
"pls" to "pulsechain",
|
||||
"pls/test" to "pulsechain/test",
|
||||
"zkSyncEra" to "zksync",
|
||||
"zkSyncEra/test" to "zksync/test",
|
||||
"polygonZkEVM" to "polygon-zkevm",
|
||||
"polygonZkEVM/test" to "polygon-zkevm/test",
|
||||
"flare" to "flare-network",
|
||||
"flare/test" to "flare-network/test",
|
||||
"playa3ull" to "playa3ull-games",
|
||||
"sei" to "sei-network",
|
||||
"sei/test" to "sei-network/test",
|
||||
"casper" to "casper-network",
|
||||
"casper/test" to "casper-network/test",
|
||||
"odyssey" to "dione",
|
||||
"odyssey/test" to "dione/test",
|
||||
"hyperliquid" to "hyperevm",
|
||||
"hyperliquid/test" to "hyperevm/test",
|
||||
"quai" to "quai-network",
|
||||
"quai/test" to "quai-network/test",
|
||||
"manta/test" to "manta-pacific/test",
|
||||
"dischain" to "ethereumfair",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,224 @@
|
|||
package com.tangem.datasource.local.preferences.utils
|
||||
|
||||
import androidx.datastore.preferences.core.mutablePreferencesOf
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import com.tangem.datasource.local.preferences.PreferencesKeys
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class SwapCurrencyIdMigrationTest {
|
||||
|
||||
private val migration = SwapCurrencyIdMigration()
|
||||
|
||||
// region shouldMigrate
|
||||
|
||||
@Test
|
||||
fun `shouldMigrate returns true when swap transactions key exists`() = runTest {
|
||||
val prefs = mutablePreferencesOf(PreferencesKeys.SWAP_TRANSACTIONS_KEY to "[]")
|
||||
|
||||
assertThat(migration.shouldMigrate(prefs)).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `shouldMigrate returns true when last swapped currency key exists`() = runTest {
|
||||
val prefs = mutablePreferencesOf(PreferencesKeys.LAST_SWAPPED_CRYPTOCURRENCY_ID_KEY to "[]")
|
||||
|
||||
assertThat(migration.shouldMigrate(prefs)).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `shouldMigrate returns true when both keys exist`() = runTest {
|
||||
val prefs = mutablePreferencesOf(
|
||||
PreferencesKeys.SWAP_TRANSACTIONS_KEY to "[]",
|
||||
PreferencesKeys.LAST_SWAPPED_CRYPTOCURRENCY_ID_KEY to "[]",
|
||||
)
|
||||
|
||||
assertThat(migration.shouldMigrate(prefs)).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `shouldMigrate returns false when no keys exist`() = runTest {
|
||||
val prefs = mutablePreferencesOf()
|
||||
|
||||
assertThat(migration.shouldMigrate(prefs)).isFalse()
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region migrate — coin IDs without derivation path
|
||||
|
||||
@Test
|
||||
fun `migrates simple coin ID - ETH to ethereum`() = runTest {
|
||||
val result = migrateLastSwapped(currencyIdJson("coin${BS}ETH${BE}ethereum"))
|
||||
|
||||
assertThat(result).isEqualTo(currencyIdJson("coin${BS}ethereum${BE}ethereum"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `migrates simple coin ID - BTC to bitcoin`() = runTest {
|
||||
val result = migrateLastSwapped(currencyIdJson("coin${BS}BTC${BE}bitcoin"))
|
||||
|
||||
assertThat(result).isEqualTo(currencyIdJson("coin${BS}bitcoin${BE}bitcoin"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `migrates BSC to binance-smart-chain`() = runTest {
|
||||
val result = migrateLastSwapped(currencyIdJson("coin${BS}BSC${BE}binancecoin"))
|
||||
|
||||
assertThat(result).isEqualTo(currencyIdJson("coin${BS}binance-smart-chain${BE}binancecoin"))
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region migrate — coin IDs with derivation path
|
||||
|
||||
@Test
|
||||
fun `migrates coin ID with derivation path`() = runTest {
|
||||
val result = migrateLastSwapped(currencyIdJson("coin${BS}ETH${DP}12367123${BE}ethereum"))
|
||||
|
||||
assertThat(result).isEqualTo(currencyIdJson("coin${BS}ethereum${DP}12367123${BE}ethereum"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `migrates POLYGON with derivation path`() = runTest {
|
||||
val result = migrateLastSwapped(currencyIdJson("coin${BS}POLYGON${DP}99999${BE}polygon-pos"))
|
||||
|
||||
assertThat(result).isEqualTo(currencyIdJson("coin${BS}polygon-pos${DP}99999${BE}polygon-pos"))
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region migrate — token IDs
|
||||
|
||||
@Test
|
||||
fun `migrates token ID with contract address`() = runTest {
|
||||
val result = migrateLastSwapped(currencyIdJson("token${BS}ETH${BE}usdt${CA}0xdAC17"))
|
||||
|
||||
assertThat(result).isEqualTo(currencyIdJson("token${BS}ethereum${BE}usdt${CA}0xdAC17"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `migrates token ID with derivation path and contract address`() = runTest {
|
||||
val result = migrateLastSwapped(
|
||||
currencyIdJson("token${BS}ETH${DP}12345${BE}usdt${CA}0xdAC17"),
|
||||
)
|
||||
|
||||
assertThat(result).isEqualTo(
|
||||
currencyIdJson("token${BS}ethereum${DP}12345${BE}usdt${CA}0xdAC17"),
|
||||
)
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region migrate — swap transactions (both from and to IDs)
|
||||
|
||||
@Test
|
||||
fun `migrates both fromCryptoCurrencyId and toCryptoCurrencyId`() = runTest {
|
||||
val from = "coin${BS}ETH${BE}ethereum"
|
||||
val to = "coin${BS}BTC${BE}bitcoin"
|
||||
val oldJson = "[{\"fromCryptoCurrencyId\":\"$from\",\"toCryptoCurrencyId\":\"$to\"}]"
|
||||
|
||||
val expectedFrom = "coin${BS}ethereum${BE}ethereum"
|
||||
val expectedTo = "coin${BS}bitcoin${BE}bitcoin"
|
||||
val expected = "[{\"fromCryptoCurrencyId\":\"$expectedFrom\",\"toCryptoCurrencyId\":\"$expectedTo\"}]"
|
||||
|
||||
val result = migrateSwapTransactions(oldJson)
|
||||
|
||||
assertThat(result).isEqualTo(expected)
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region migrate — no-op cases
|
||||
|
||||
@Test
|
||||
fun `does not modify already migrated IDs`() = runTest {
|
||||
val json = currencyIdJson("coin${BS}ethereum${BE}ethereum")
|
||||
|
||||
val result = migrateLastSwapped(json)
|
||||
|
||||
assertThat(result).isEqualTo(json)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `does not modify IDs where blockchain id equals networkId`() = runTest {
|
||||
val json = currencyIdJson("coin${BS}cosmos${BE}cosmos")
|
||||
|
||||
val result = migrateLastSwapped(json)
|
||||
|
||||
assertThat(result).isEqualTo(json)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `does not modify empty list`() = runTest {
|
||||
val result = migrateLastSwapped("[]")
|
||||
|
||||
assertThat(result).isEqualTo("[]")
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region migrate — multiple entries
|
||||
|
||||
@Test
|
||||
fun `migrates multiple entries in list`() = runTest {
|
||||
val old1 = currencyIdValue("coin${BS}ETH${BE}ethereum")
|
||||
val old2 = currencyIdValue("coin${BS}TRON${BE}tron")
|
||||
val oldJson = "[$old1,$old2]"
|
||||
|
||||
val new1 = currencyIdValue("coin${BS}ethereum${BE}ethereum")
|
||||
val new2 = currencyIdValue("coin${BS}tron${BE}tron")
|
||||
val expected = "[$new1,$new2]"
|
||||
|
||||
val result = migrateLastSwapped(oldJson)
|
||||
|
||||
assertThat(result).isEqualTo(expected)
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region migrate — preserves unrelated keys
|
||||
|
||||
@Test
|
||||
fun `preserves unrelated preference keys`() = runTest {
|
||||
val unrelatedKey = PreferencesKeys.BALANCE_HIDING_SETTINGS_KEY
|
||||
val unrelatedValue = "some_value"
|
||||
val prefs = mutablePreferencesOf(
|
||||
PreferencesKeys.LAST_SWAPPED_CRYPTOCURRENCY_ID_KEY to currencyIdJson("coin${BS}ETH${BE}ethereum"),
|
||||
unrelatedKey to unrelatedValue,
|
||||
)
|
||||
|
||||
val result = migration.migrate(prefs)
|
||||
|
||||
assertThat(result[unrelatedKey]).isEqualTo(unrelatedValue)
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region helpers
|
||||
|
||||
private suspend fun migrateLastSwapped(json: String): String? {
|
||||
val prefs = mutablePreferencesOf(PreferencesKeys.LAST_SWAPPED_CRYPTOCURRENCY_ID_KEY to json)
|
||||
val result = migration.migrate(prefs)
|
||||
return result[PreferencesKeys.LAST_SWAPPED_CRYPTOCURRENCY_ID_KEY]
|
||||
}
|
||||
|
||||
private suspend fun migrateSwapTransactions(json: String): String? {
|
||||
val prefs = mutablePreferencesOf(PreferencesKeys.SWAP_TRANSACTIONS_KEY to json)
|
||||
val result = migration.migrate(prefs)
|
||||
return result[PreferencesKeys.SWAP_TRANSACTIONS_KEY]
|
||||
}
|
||||
|
||||
private fun currencyIdJson(id: String): String = "[${currencyIdValue(id)}]"
|
||||
|
||||
private fun currencyIdValue(id: String): String = "{\"cryptoCurrencyId\":\"$id\"}"
|
||||
|
||||
private companion object {
|
||||
const val BS = '\u27E8' // ⟨ body start
|
||||
const val BE = '\u27E9' // ⟩ body end
|
||||
const val DP = '\u2192' // → derivation path delimiter
|
||||
const val CA = '\u2693' // ⚓ contract address delimiter
|
||||
}
|
||||
|
||||
// endregion
|
||||
}
|
||||
|
|
@ -136,8 +136,7 @@ class NetworkFactory @Inject constructor(
|
|||
|
||||
return runCatching {
|
||||
Network(
|
||||
id = Network.ID(value = blockchain.id, derivationPath = derivationPath),
|
||||
backendId = blockchain.toNetworkId(),
|
||||
id = Network.ID(value = blockchain.toNetworkId(), derivationPath = derivationPath),
|
||||
name = blockchain.fullName,
|
||||
isTestnet = blockchain.isTestnet(),
|
||||
derivationPath = derivationPath,
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.tangem.data.common.network
|
|||
import com.google.common.truth.Truth
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchainsdk.utils.ExcludedBlockchains
|
||||
import com.tangem.blockchainsdk.utils.toNetworkId
|
||||
import com.tangem.common.test.domain.card.MockScanResponseFactory
|
||||
import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory
|
||||
import com.tangem.common.test.domain.wallet.MockUserWalletFactory
|
||||
|
|
@ -187,7 +188,7 @@ class NetworkFactoryTest {
|
|||
userWallet = userWallet,
|
||||
expected = MockCryptoCurrencyFactory().ethereum.network.copy(
|
||||
id = Network.ID(
|
||||
value = Blockchain.Ethereum.id,
|
||||
value = Blockchain.Ethereum.toNetworkId(),
|
||||
derivationPath = expectedDerivationPath,
|
||||
),
|
||||
derivationPath = expectedDerivationPath,
|
||||
|
|
@ -201,12 +202,12 @@ class NetworkFactoryTest {
|
|||
derivationPath: Network.DerivationPath,
|
||||
): CreateTestModel.Second {
|
||||
return CreateTestModel.Second(
|
||||
networkId = Network.ID(value = Blockchain.Ethereum.id, derivationPath = derivationPath),
|
||||
networkId = Network.ID(value = Blockchain.Ethereum.toNetworkId(), derivationPath = derivationPath),
|
||||
derivationPath = derivationPath,
|
||||
userWallet = userWallet,
|
||||
expected = MockCryptoCurrencyFactory().ethereum.network.copy(
|
||||
id = Network.ID(
|
||||
value = Blockchain.Ethereum.id,
|
||||
value = Blockchain.Ethereum.toNetworkId(),
|
||||
derivationPath = derivationPath,
|
||||
),
|
||||
derivationPath = derivationPath,
|
||||
|
|
@ -227,7 +228,7 @@ class NetworkFactoryTest {
|
|||
derivationStyleProvider = derivationStyleProvider,
|
||||
canHandleTokens = canHandleTokens,
|
||||
expected = MockCryptoCurrencyFactory().ethereum.network.copy(
|
||||
id = Network.ID(value = Blockchain.Ethereum.id, derivationPath = expectedDerivationPath),
|
||||
id = Network.ID(value = Blockchain.Ethereum.toNetworkId(), derivationPath = expectedDerivationPath),
|
||||
derivationPath = expectedDerivationPath,
|
||||
canHandleTokens = canHandleTokens,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.data.networks.converters
|
||||
|
||||
import com.tangem.blockchainsdk.utils.toBlockchain
|
||||
import com.tangem.datasource.local.network.entity.NetworkStatusDM
|
||||
import com.tangem.domain.models.network.NetworkStatus
|
||||
import com.tangem.utils.converter.Converter
|
||||
|
|
@ -15,17 +16,18 @@ internal object NetworkStatusDataModelConverter : Converter<NetworkStatus, Netwo
|
|||
return when (val status = value.value) {
|
||||
is NetworkStatus.Verified -> {
|
||||
val address = NetworkAddressConverter.convertBack(value = status.address)
|
||||
val blockchainId = value.network.toBlockchain().id
|
||||
val amountsConverter = NetworkAmountsConverter(
|
||||
rawNetworkId = value.network.rawId,
|
||||
rawNetworkId = blockchainId,
|
||||
derivationPath = value.network.derivationPath,
|
||||
)
|
||||
val yieldSupplyStatusConverter = NetworkYieldSupplyStatusConverter(
|
||||
rawNetworkId = value.network.rawId,
|
||||
rawNetworkId = blockchainId,
|
||||
derivationPath = value.network.derivationPath,
|
||||
)
|
||||
|
||||
NetworkStatusDM.Verified(
|
||||
networkId = NetworkStatusDM.ID(value = value.network.rawId),
|
||||
networkId = NetworkStatusDM.ID(value = blockchainId),
|
||||
derivationPath = NetworkDerivationPathConverter.convertBack(value = value.network.derivationPath),
|
||||
selectedAddress = address.selectedAddress,
|
||||
availableAddresses = address.addresses,
|
||||
|
|
@ -35,9 +37,10 @@ internal object NetworkStatusDataModelConverter : Converter<NetworkStatus, Netwo
|
|||
}
|
||||
is NetworkStatus.NoAccount -> {
|
||||
val address = NetworkAddressConverter.convertBack(value = status.address)
|
||||
val blockchainId = value.network.toBlockchain().id
|
||||
|
||||
NetworkStatusDM.NoAccount(
|
||||
networkId = NetworkStatusDM.ID(value = value.network.rawId),
|
||||
networkId = NetworkStatusDM.ID(value = blockchainId),
|
||||
derivationPath = NetworkDerivationPathConverter.convertBack(value = value.network.derivationPath),
|
||||
selectedAddress = address.selectedAddress,
|
||||
availableAddresses = address.addresses,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package com.tangem.data.networks.converters
|
||||
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchainsdk.utils.toNetworkId
|
||||
import com.tangem.data.networks.models.SimpleNetworkStatus
|
||||
import com.tangem.datasource.local.network.entity.NetworkStatusDM
|
||||
import com.tangem.domain.models.StatusSource
|
||||
|
|
@ -23,14 +25,15 @@ internal object SimpleNetworkStatusConverter : Converter<NetworkStatusDM, Simple
|
|||
)
|
||||
|
||||
val derivationPath = NetworkDerivationPathConverter.convert(value = value.derivationPath)
|
||||
val rawNetworkId = value.networkId.value
|
||||
|
||||
val amountsConverter = NetworkAmountsConverter(
|
||||
rawNetworkId = value.networkId.value,
|
||||
rawNetworkId = rawNetworkId,
|
||||
derivationPath = derivationPath,
|
||||
)
|
||||
|
||||
val yieldSupplyStatusConverter = NetworkYieldSupplyStatusConverter(
|
||||
rawNetworkId = value.networkId.value,
|
||||
rawNetworkId = rawNetworkId,
|
||||
derivationPath = derivationPath,
|
||||
)
|
||||
|
||||
|
|
@ -54,9 +57,11 @@ internal object SimpleNetworkStatusConverter : Converter<NetworkStatusDM, Simple
|
|||
}
|
||||
}
|
||||
|
||||
val rawId = Blockchain.fromId(rawNetworkId).toNetworkId()
|
||||
|
||||
return SimpleNetworkStatus(
|
||||
id = Network.ID(
|
||||
value = value.networkId.value,
|
||||
value = rawId,
|
||||
derivationPath = NetworkDerivationPathConverter.convert(value = value.derivationPath),
|
||||
),
|
||||
value = status,
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.tangem.data.networks.store
|
|||
|
||||
import android.content.Context
|
||||
import androidx.datastore.core.DataStore
|
||||
import com.tangem.blockchainsdk.utils.toBlockchain
|
||||
import com.tangem.data.networks.converters.NetworkStatusDataModelConverter
|
||||
import com.tangem.data.networks.converters.SimpleNetworkStatusConverter
|
||||
import com.tangem.data.networks.models.SimpleNetworkStatus
|
||||
|
|
@ -27,15 +28,15 @@ internal typealias WalletIdWithStatusDM = Map<String, Set<NetworkStatusDM>>
|
|||
* Default implementation of [NetworksStatusesStore]
|
||||
*
|
||||
* @param context context
|
||||
* @param scope app coroutine scope
|
||||
* @property runtimeStore runtime store
|
||||
* @property persistenceDataStore persistence store
|
||||
* @param dispatchers dispatchers
|
||||
*/
|
||||
internal class DefaultNetworksStatusesStore(
|
||||
context: Context,
|
||||
scope: AppCoroutineScope,
|
||||
private val runtimeStore: RuntimeSharedStore<WalletIdWithSimpleStatus>,
|
||||
private val persistenceDataStore: DataStore<WalletIdWithStatusDM>,
|
||||
private val scope: AppCoroutineScope,
|
||||
) : NetworksStatusesStore {
|
||||
|
||||
init {
|
||||
|
|
@ -112,7 +113,8 @@ internal class DefaultNetworksStatusesStore(
|
|||
storedStatuses.toMutableMap().apply {
|
||||
val updatedValues = this[userWalletId.stringValue].orEmpty().filterNot {
|
||||
networks.any { network ->
|
||||
it.networkId.value == network.rawId && it.derivationPath.value == network.derivationPath.value
|
||||
it.networkId.value == network.toBlockchain().id &&
|
||||
it.derivationPath.value == network.derivationPath.value
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.data.networks.converters
|
||||
|
||||
import com.google.common.truth.Truth
|
||||
import com.tangem.blockchainsdk.utils.toBlockchain
|
||||
import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory
|
||||
import com.tangem.datasource.local.network.entity.NetworkStatusDM
|
||||
import com.tangem.datasource.local.network.entity.NetworkStatusDM.*
|
||||
|
|
@ -74,7 +75,7 @@ internal class NetworkStatusDataModelConverterTest {
|
|||
),
|
||||
),
|
||||
expected = Verified(
|
||||
networkId = ID(network.rawId),
|
||||
networkId = ID(network.toBlockchain().id),
|
||||
derivationPath = DerivationPath(
|
||||
value = "",
|
||||
type = DerivationPath.Type.NONE,
|
||||
|
|
@ -119,7 +120,7 @@ internal class NetworkStatusDataModelConverterTest {
|
|||
),
|
||||
),
|
||||
expected = NoAccount(
|
||||
networkId = ID(network.rawId),
|
||||
networkId = ID(network.toBlockchain().id),
|
||||
derivationPath = DerivationPath(
|
||||
value = "",
|
||||
type = DerivationPath.Type.NONE,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.data.networks.converters
|
||||
|
||||
import com.google.common.truth.Truth
|
||||
import com.tangem.blockchainsdk.utils.toBlockchain
|
||||
import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory
|
||||
import com.tangem.data.networks.models.SimpleNetworkStatus
|
||||
import com.tangem.datasource.local.network.entity.NetworkStatusDM
|
||||
|
|
@ -48,7 +49,7 @@ internal class SimpleNetworkStatusConverterTest {
|
|||
// region Verified
|
||||
ConvertModel(
|
||||
value = Verified(
|
||||
networkId = ID(network.rawId),
|
||||
networkId = ID(network.toBlockchain().id),
|
||||
derivationPath = DerivationPath(
|
||||
value = "card",
|
||||
type = DerivationPath.Type.CARD,
|
||||
|
|
@ -74,7 +75,7 @@ internal class SimpleNetworkStatusConverterTest {
|
|||
),
|
||||
expected = SimpleNetworkStatus(
|
||||
id = Network.ID(
|
||||
value = network.rawId,
|
||||
value = network.backendId,
|
||||
derivationPath = Network.DerivationPath.Card("card"),
|
||||
),
|
||||
value = NetworkStatus.Verified(
|
||||
|
|
@ -116,7 +117,7 @@ internal class SimpleNetworkStatusConverterTest {
|
|||
// region NoAccount
|
||||
ConvertModel(
|
||||
value = NoAccount(
|
||||
networkId = ID(network.rawId),
|
||||
networkId = ID(network.toBlockchain().id),
|
||||
derivationPath = DerivationPath(
|
||||
value = "card",
|
||||
type = DerivationPath.Type.CARD,
|
||||
|
|
@ -137,7 +138,7 @@ internal class SimpleNetworkStatusConverterTest {
|
|||
),
|
||||
expected = SimpleNetworkStatus(
|
||||
id = Network.ID(
|
||||
value = network.rawId,
|
||||
value = network.backendId,
|
||||
derivationPath = Network.DerivationPath.Card("card"),
|
||||
),
|
||||
value = NetworkStatus.NoAccount(
|
||||
|
|
@ -168,7 +169,7 @@ internal class SimpleNetworkStatusConverterTest {
|
|||
// region Error
|
||||
ConvertModel(
|
||||
value = Verified(
|
||||
networkId = ID(network.rawId),
|
||||
networkId = ID(network.toBlockchain().id),
|
||||
derivationPath = DerivationPath(
|
||||
value = "card",
|
||||
type = DerivationPath.Type.CARD,
|
||||
|
|
@ -189,7 +190,7 @@ internal class SimpleNetworkStatusConverterTest {
|
|||
),
|
||||
ConvertModel(
|
||||
value = Verified(
|
||||
networkId = ID(network.rawId),
|
||||
networkId = ID(network.toBlockchain().id),
|
||||
derivationPath = DerivationPath(
|
||||
value = "card",
|
||||
type = DerivationPath.Type.CARD,
|
||||
|
|
@ -205,7 +206,7 @@ internal class SimpleNetworkStatusConverterTest {
|
|||
),
|
||||
ConvertModel(
|
||||
value = Verified(
|
||||
networkId = ID(network.rawId),
|
||||
networkId = ID(network.toBlockchain().id),
|
||||
derivationPath = DerivationPath(
|
||||
value = "card",
|
||||
type = DerivationPath.Type.CARD,
|
||||
|
|
@ -230,7 +231,7 @@ internal class SimpleNetworkStatusConverterTest {
|
|||
),
|
||||
ConvertModel(
|
||||
value = NoAccount(
|
||||
networkId = ID(network.rawId),
|
||||
networkId = ID(network.toBlockchain().id),
|
||||
derivationPath = DerivationPath(
|
||||
value = "card",
|
||||
type = DerivationPath.Type.CARD,
|
||||
|
|
@ -255,7 +256,7 @@ internal class SimpleNetworkStatusConverterTest {
|
|||
),
|
||||
ConvertModel(
|
||||
value = NoAccount(
|
||||
networkId = ID(network.rawId),
|
||||
networkId = ID(network.toBlockchain().id),
|
||||
derivationPath = DerivationPath(
|
||||
value = "card",
|
||||
type = DerivationPath.Type.CARD,
|
||||
|
|
@ -276,7 +277,7 @@ internal class SimpleNetworkStatusConverterTest {
|
|||
),
|
||||
ConvertModel(
|
||||
value = NoAccount(
|
||||
networkId = ID(network.rawId),
|
||||
networkId = ID(network.toBlockchain().id),
|
||||
derivationPath = DerivationPath(
|
||||
value = "card",
|
||||
type = DerivationPath.Type.CARD,
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ internal class CommonNetworkStatusFetcherTest {
|
|||
val userWalletId = UserWalletId("011")
|
||||
val network = cryptoCurrencyFactory.ethereum.network
|
||||
val extraTokens = setOf(
|
||||
cryptoCurrencyFactory.createToken(Blockchain.Ethereum) as CryptoCurrency.Token,
|
||||
cryptoCurrencyFactory.createToken(Blockchain.Ethereum),
|
||||
)
|
||||
val updateException = IllegalStateException()
|
||||
|
||||
|
|
@ -80,7 +80,7 @@ internal class CommonNetworkStatusFetcherTest {
|
|||
val userWalletId = UserWalletId("011")
|
||||
val network = cryptoCurrencyFactory.ethereum.network
|
||||
val extraTokens = setOf(
|
||||
cryptoCurrencyFactory.createToken(Blockchain.Ethereum) as CryptoCurrency.Token,
|
||||
cryptoCurrencyFactory.createToken(Blockchain.Ethereum),
|
||||
)
|
||||
val updateResult = model.updateResult
|
||||
val status = model.status
|
||||
|
|
@ -143,15 +143,15 @@ internal class CommonNetworkStatusFetcherTest {
|
|||
it.copy(
|
||||
amounts = mapOf(
|
||||
CryptoCurrency.ID.fromValue(
|
||||
value = "token⟨ETH⟩NEVER-MIND⚓NEVER-MIND",
|
||||
value = "token⟨ethereum⟩NEVER-MIND⚓NEVER-MIND",
|
||||
) to NetworkStatus.Amount.NotFound,
|
||||
),
|
||||
pendingTransactions = mapOf(
|
||||
CryptoCurrency.ID.fromValue(value = "token⟨ETH⟩NEVER-MIND⚓NEVER-MIND") to emptySet(),
|
||||
CryptoCurrency.ID.fromValue(value = "token⟨ethereum⟩NEVER-MIND⚓NEVER-MIND") to emptySet(),
|
||||
),
|
||||
yieldSupplyStatuses = mapOf(
|
||||
CryptoCurrency.ID.fromValue(
|
||||
value = "token⟨ETH⟩NEVER-MIND⚓NEVER-MIND",
|
||||
value = "token⟨ethereum⟩NEVER-MIND⚓NEVER-MIND",
|
||||
) to null,
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ internal class Bip321PaymentUriParserTest {
|
|||
|
||||
@Test
|
||||
fun `includes tokens on matching network`() {
|
||||
val btcToken = buildToken("BTC", "RUNE", "contractAddr")
|
||||
val btcToken = buildToken("bitcoin", "RUNE", "contractAddr")
|
||||
|
||||
val result = parser.parse(
|
||||
qrCode = "bitcoin:1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa?amount=0.01",
|
||||
|
|
@ -263,7 +263,13 @@ internal class Bip321PaymentUriParserTest {
|
|||
|
||||
@Test
|
||||
fun `memo on network with memo support is not unsupported`() {
|
||||
val xrpCoin = buildCoin("XRP", "XRP", "XRP", decimals = 6, extrasType = Network.TransactionExtrasType.DESTINATION_TAG)
|
||||
val xrpCoin = buildCoin(
|
||||
rawNetworkId = "xrp",
|
||||
name = "XRP",
|
||||
symbol = "XRP",
|
||||
decimals = 6,
|
||||
extrasType = Network.TransactionExtrasType.DESTINATION_TAG,
|
||||
)
|
||||
|
||||
val result = parser.parse(
|
||||
qrCode = "ripple:rAddress?dt=12345",
|
||||
|
|
@ -299,9 +305,9 @@ internal class Bip321PaymentUriParserTest {
|
|||
}
|
||||
}
|
||||
|
||||
private val bitcoinCoin = buildCoin("BTC", "Bitcoin", "BTC", decimals = 8)
|
||||
private val litecoinCoin = buildCoin("LTC", "Litecoin", "LTC", decimals = 8)
|
||||
private val dogecoinCoin = buildCoin("DOGE", "Dogecoin", "DOGE", decimals = 8)
|
||||
private val bitcoinCoin = buildCoin("bitcoin", "Bitcoin", "BTC", decimals = 8)
|
||||
private val litecoinCoin = buildCoin("litecoin", "Litecoin", "LTC", decimals = 8)
|
||||
private val dogecoinCoin = buildCoin("dogecoin", "Dogecoin", "DOGE", decimals = 8)
|
||||
|
||||
private fun buildCoin(
|
||||
rawNetworkId: String,
|
||||
|
|
@ -349,8 +355,7 @@ internal class Bip321PaymentUriParserTest {
|
|||
extrasType: Network.TransactionExtrasType = Network.TransactionExtrasType.NONE,
|
||||
): Network {
|
||||
return Network(
|
||||
id = Network.ID(Network.RawID(rawNetworkId), Network.DerivationPath.None),
|
||||
backendId = rawNetworkId,
|
||||
id = Network.ID(value = rawNetworkId, derivationPath = Network.DerivationPath.None),
|
||||
name = name,
|
||||
currencySymbol = symbol,
|
||||
derivationPath = Network.DerivationPath.None,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package com.tangem.data.qrscanning
|
||||
|
||||
import com.google.common.truth.Truth
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.data.qrscanning.parser.QrContentClassifierParser
|
||||
import com.tangem.data.qrscanning.repository.DefaultQrScanningEventsRepository
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
|
|
@ -78,7 +77,8 @@ internal class DefaultQrScanningEventsRepositoryTest {
|
|||
|
||||
@Test
|
||||
fun testBip021() {
|
||||
every { network.id.rawId.value } returns Blockchain.Bitcoin.id
|
||||
every { network.id } returns Network.ID(value = "bitcoin", derivationPath = Network.DerivationPath.None)
|
||||
every { network.backendId } returns "bitcoin"
|
||||
positiveCase(
|
||||
"$schema1:$address1",
|
||||
QrResult(address = address1),
|
||||
|
|
@ -128,7 +128,8 @@ internal class DefaultQrScanningEventsRepositoryTest {
|
|||
|
||||
@Test
|
||||
fun testErc681Coin() {
|
||||
every { network.id.rawId.value } returns Blockchain.Ethereum.id
|
||||
every { network.id } returns Network.ID(value = "ethereum", derivationPath = Network.DerivationPath.None)
|
||||
every { network.backendId } returns "ethereum"
|
||||
positiveCase(
|
||||
address2,
|
||||
QrResult(address = address2),
|
||||
|
|
@ -183,7 +184,8 @@ internal class DefaultQrScanningEventsRepositoryTest {
|
|||
|
||||
@Test
|
||||
fun testErc681Token() {
|
||||
every { network.id.rawId.value } returns Blockchain.Ethereum.id
|
||||
every { network.id } returns Network.ID(value = "ethereum", derivationPath = Network.DerivationPath.None)
|
||||
every { network.backendId } returns "ethereum"
|
||||
positiveCase(
|
||||
address2,
|
||||
QrResult(address = address2),
|
||||
|
|
|
|||
|
|
@ -382,8 +382,7 @@ internal class Eip681PaymentUriParserTest {
|
|||
|
||||
private fun buildNetwork(rawNetworkId: String): Network {
|
||||
return Network(
|
||||
id = Network.ID(Network.RawID(rawNetworkId), Network.DerivationPath.None),
|
||||
backendId = rawNetworkId,
|
||||
id = Network.ID(value = rawNetworkId, derivationPath = Network.DerivationPath.None),
|
||||
name = rawNetworkId,
|
||||
currencySymbol = rawNetworkId.take(3).uppercase(),
|
||||
derivationPath = Network.DerivationPath.None,
|
||||
|
|
|
|||
|
|
@ -233,8 +233,7 @@ internal class QrContentClassifierTest {
|
|||
|
||||
private fun buildNetwork(rawNetworkId: String): Network {
|
||||
return Network(
|
||||
id = Network.ID(Network.RawID(rawNetworkId), Network.DerivationPath.None),
|
||||
backendId = rawNetworkId,
|
||||
id = Network.ID(value = rawNetworkId, derivationPath = Network.DerivationPath.None),
|
||||
name = rawNetworkId,
|
||||
currencySymbol = rawNetworkId.take(3).uppercase(),
|
||||
derivationPath = Network.DerivationPath.None,
|
||||
|
|
|
|||
|
|
@ -198,13 +198,13 @@ internal class SolanaPaymentUriParserTest {
|
|||
}
|
||||
}
|
||||
|
||||
private val solanaNetwork = buildNetwork("SOLANA", "Solana", "SOL")
|
||||
private val solanaNetwork = buildNetwork("solana", "Solana", "SOL")
|
||||
|
||||
private val solanaCoin = CryptoCurrency.Coin(
|
||||
id = CryptoCurrency.ID(
|
||||
prefix = CryptoCurrency.ID.Prefix.COIN_PREFIX,
|
||||
body = CryptoCurrency.ID.Body.NetworkId("SOLANA"),
|
||||
suffix = CryptoCurrency.ID.Suffix.RawID("SOLANA"),
|
||||
body = CryptoCurrency.ID.Body.NetworkId("solana"),
|
||||
suffix = CryptoCurrency.ID.Suffix.RawID("solana"),
|
||||
),
|
||||
network = solanaNetwork,
|
||||
name = "Solana",
|
||||
|
|
@ -217,7 +217,7 @@ internal class SolanaPaymentUriParserTest {
|
|||
private val usdcToken = CryptoCurrency.Token(
|
||||
id = CryptoCurrency.ID(
|
||||
prefix = CryptoCurrency.ID.Prefix.TOKEN_PREFIX,
|
||||
body = CryptoCurrency.ID.Body.NetworkId("SOLANA"),
|
||||
body = CryptoCurrency.ID.Body.NetworkId("solana"),
|
||||
suffix = CryptoCurrency.ID.Suffix.RawID("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"),
|
||||
),
|
||||
network = solanaNetwork,
|
||||
|
|
@ -231,8 +231,7 @@ internal class SolanaPaymentUriParserTest {
|
|||
|
||||
private fun buildNetwork(rawNetworkId: String, name: String, symbol: String): Network {
|
||||
return Network(
|
||||
id = Network.ID(Network.RawID(rawNetworkId), Network.DerivationPath.None),
|
||||
backendId = rawNetworkId,
|
||||
id = Network.ID(value = rawNetworkId, derivationPath = Network.DerivationPath.None),
|
||||
name = name,
|
||||
currencySymbol = symbol,
|
||||
derivationPath = Network.DerivationPath.None,
|
||||
|
|
|
|||
|
|
@ -238,13 +238,13 @@ internal class TronPaymentUriParserTest {
|
|||
}
|
||||
}
|
||||
|
||||
private val tronNetwork = buildNetwork("TRON", "Tron", "TRX")
|
||||
private val tronNetwork = buildNetwork("tron", "Tron", "TRX")
|
||||
|
||||
private val tronCoin = CryptoCurrency.Coin(
|
||||
id = CryptoCurrency.ID(
|
||||
prefix = CryptoCurrency.ID.Prefix.COIN_PREFIX,
|
||||
body = CryptoCurrency.ID.Body.NetworkId("TRON"),
|
||||
suffix = CryptoCurrency.ID.Suffix.RawID("TRON"),
|
||||
body = CryptoCurrency.ID.Body.NetworkId("tron"),
|
||||
suffix = CryptoCurrency.ID.Suffix.RawID("tron"),
|
||||
),
|
||||
network = tronNetwork,
|
||||
name = "Tron",
|
||||
|
|
@ -257,7 +257,7 @@ internal class TronPaymentUriParserTest {
|
|||
private val usdtToken = CryptoCurrency.Token(
|
||||
id = CryptoCurrency.ID(
|
||||
prefix = CryptoCurrency.ID.Prefix.TOKEN_PREFIX,
|
||||
body = CryptoCurrency.ID.Body.NetworkId("TRON"),
|
||||
body = CryptoCurrency.ID.Body.NetworkId("tron"),
|
||||
suffix = CryptoCurrency.ID.Suffix.RawID("TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t"),
|
||||
),
|
||||
network = tronNetwork,
|
||||
|
|
@ -271,8 +271,7 @@ internal class TronPaymentUriParserTest {
|
|||
|
||||
private fun buildNetwork(rawNetworkId: String, name: String, symbol: String): Network {
|
||||
return Network(
|
||||
id = Network.ID(Network.RawID(rawNetworkId), Network.DerivationPath.None),
|
||||
backendId = rawNetworkId,
|
||||
id = Network.ID(value = rawNetworkId, derivationPath = Network.DerivationPath.None),
|
||||
name = name,
|
||||
currencySymbol = symbol,
|
||||
derivationPath = Network.DerivationPath.None,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,11 @@ package com.tangem.data.tokens.repository
|
|||
|
||||
import com.tangem.blockchain.blockchains.ethereum.eip1559.isGaslessTxSupported
|
||||
import com.tangem.blockchain.blockchains.polkadot.ExistentialDepositProvider
|
||||
import com.tangem.blockchain.common.*
|
||||
import com.tangem.blockchain.common.FeeResourceAmountProvider
|
||||
import com.tangem.blockchain.common.MinimumSendAmountProvider
|
||||
import com.tangem.blockchain.common.ReserveAmountProvider
|
||||
import com.tangem.blockchain.common.UtxoAmountLimitProvider
|
||||
import com.tangem.blockchainsdk.utils.toBlockchain
|
||||
import com.tangem.common.getTotalStakingBalance
|
||||
import com.tangem.data.tokens.converters.UtxoConverter
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
|
|
@ -67,7 +71,7 @@ internal class DefaultCurrencyChecksRepository(
|
|||
}
|
||||
|
||||
override fun isNetworkSupportedForGaslessTx(network: Network): Boolean {
|
||||
val blockchain = Blockchain.fromId(network.rawId)
|
||||
val blockchain = network.toBlockchain()
|
||||
return blockchain.isGaslessTxSupported
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package com.tangem.data.transaction
|
||||
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.Token
|
||||
import com.tangem.blockchainsdk.utils.toBlockchain
|
||||
import com.tangem.data.common.currency.ResponseCryptoCurrenciesFactory
|
||||
import com.tangem.data.transaction.convertes.GaslessSignedTransactionResultConverter
|
||||
import com.tangem.data.transaction.convertes.GaslessTransactionRequestBuilder
|
||||
|
|
@ -45,7 +45,7 @@ class DefaultGaslessTransactionRepository(
|
|||
|
||||
val supportedTokensData = gaslessTxServiceApi.getSupportedTokens().getOrThrow()
|
||||
if (supportedTokensData.isSuccess) {
|
||||
val networkBlockchain = Blockchain.fromId(network.rawId)
|
||||
val networkBlockchain = network.toBlockchain()
|
||||
val supportedTokens = supportedTokensData.result.tokens
|
||||
.filter {
|
||||
it.chainId == networkBlockchain.getChainId()
|
||||
|
|
@ -100,7 +100,7 @@ class DefaultGaslessTransactionRepository(
|
|||
network: Network,
|
||||
eip7702Auth: Eip7702Authorization?,
|
||||
): GaslessSignedTransactionResult = withContext(coroutineDispatcherProvider.io) {
|
||||
val blockchain = Blockchain.fromId(network.rawId)
|
||||
val blockchain = network.toBlockchain()
|
||||
val transactionRequest = gaslessTransactionRequestBuilder.build(
|
||||
gaslessTransaction = gaslessTransactionData,
|
||||
signature = signature,
|
||||
|
|
@ -124,7 +124,7 @@ class DefaultGaslessTransactionRepository(
|
|||
}
|
||||
|
||||
override fun getChainIdForNetwork(network: Network): Int {
|
||||
val networkBlockchain = Blockchain.fromId(network.rawId)
|
||||
val networkBlockchain = network.toBlockchain()
|
||||
return networkBlockchain.getChainId() ?: error("ChainId not found for blockchain ${networkBlockchain.name}")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.tangem.data.transaction
|
|||
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.Token
|
||||
import com.tangem.blockchainsdk.utils.toBlockchain
|
||||
import com.tangem.data.common.currency.ResponseCryptoCurrenciesFactory
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.network.Network
|
||||
|
|
@ -30,7 +31,7 @@ class MockedGaslessTransactionRepository(
|
|||
}
|
||||
|
||||
override fun getChainIdForNetwork(network: Network): Int {
|
||||
val networkBlockchain = Blockchain.fromId(network.rawId)
|
||||
val networkBlockchain = network.toBlockchain()
|
||||
return networkBlockchain.getChainId() ?: error("ChainId not found for blockchain ${networkBlockchain.name}")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -171,7 +171,11 @@ class DefaultAllowanceRepositoryTest {
|
|||
|
||||
@Test
|
||||
fun `returns NotEnough when partial allowance for non-tether token`() = runTest {
|
||||
val token = buildToken(rawNetworkId = "ethereum", rawCurrencyId = "usd-coin")
|
||||
val token = buildToken(
|
||||
rawNetworkId = "ethereum",
|
||||
rawCurrencyId = "usd-coin",
|
||||
contractAddress = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
||||
)
|
||||
|
||||
coEvery {
|
||||
(approverWalletManager as Approver).getAllowance(spenderAddress, any())
|
||||
|
|
@ -187,7 +191,7 @@ class DefaultAllowanceRepositoryTest {
|
|||
|
||||
@Test
|
||||
fun `returns NotEnough when partial allowance for tether on non-ethereum network`() = runTest {
|
||||
val token = buildToken(rawNetworkId = "polygon", rawCurrencyId = "tether")
|
||||
val token = buildToken(rawNetworkId = "polygon-pos", rawCurrencyId = "tether")
|
||||
|
||||
coEvery {
|
||||
(approverWalletManager as Approver).getAllowance(spenderAddress, any())
|
||||
|
|
@ -200,7 +204,7 @@ class DefaultAllowanceRepositoryTest {
|
|||
|
||||
@Test
|
||||
fun `returns ResetNeeded when partial allowance for tether on ethereum`() = runTest {
|
||||
val token = buildToken(rawNetworkId = "ETH", rawCurrencyId = "tether")
|
||||
val token = buildToken(rawNetworkId = "ethereum", rawCurrencyId = "tether")
|
||||
|
||||
coEvery {
|
||||
(approverWalletManager as Approver).getAllowance(spenderAddress, any())
|
||||
|
|
@ -216,7 +220,7 @@ class DefaultAllowanceRepositoryTest {
|
|||
|
||||
@Test
|
||||
fun `returns ResetNeeded when partial allowance for tether on ethereum testnet`() = runTest {
|
||||
val token = buildToken(rawNetworkId = "ETH/test", rawCurrencyId = "tether")
|
||||
val token = buildToken(rawNetworkId = "ethereum/test", rawCurrencyId = "tether")
|
||||
|
||||
coEvery {
|
||||
(approverWalletManager as Approver).getAllowance(spenderAddress, any())
|
||||
|
|
@ -248,8 +252,7 @@ class DefaultAllowanceRepositoryTest {
|
|||
private fun buildNetwork(rawNetworkId: String): Network {
|
||||
val derivationPath = Network.DerivationPath.None
|
||||
return Network(
|
||||
id = Network.ID(Network.RawID(rawNetworkId), derivationPath),
|
||||
backendId = rawNetworkId,
|
||||
id = Network.ID(value = rawNetworkId, derivationPath = derivationPath),
|
||||
name = rawNetworkId.replaceFirstChar { it.uppercase() },
|
||||
currencySymbol = "ETH",
|
||||
derivationPath = derivationPath,
|
||||
|
|
@ -263,7 +266,7 @@ class DefaultAllowanceRepositoryTest {
|
|||
}
|
||||
|
||||
private fun buildToken(
|
||||
rawNetworkId: String = "ETH",
|
||||
rawNetworkId: String = "ethereum",
|
||||
rawCurrencyId: String = "tether",
|
||||
contractAddress: String = "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
||||
): CryptoCurrency.Token {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import com.reown.walletkit.client.Wallet
|
|||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.address.AddressType
|
||||
import com.tangem.blockchainsdk.utils.toBlockchain
|
||||
import com.tangem.blockchainsdk.utils.toNetworkId
|
||||
import com.tangem.data.common.currency.isCustomCoin
|
||||
import com.tangem.data.walletconnect.model.CAIP10
|
||||
import com.tangem.domain.account.status.producer.SingleAccountStatusListProducer
|
||||
|
|
@ -84,7 +85,7 @@ internal class WcNetworksConverter @Inject constructor(
|
|||
val blockchain = namespaceConverters
|
||||
.firstNotNullOfOrNull { it.toBlockchain(rawChainId) } ?: return listOf()
|
||||
|
||||
val allCoinNetwork = portfolioNetworks.filter { it.rawId == blockchain.id }
|
||||
val allCoinNetwork = portfolioNetworks.filter { it.rawId == blockchain.toNetworkId() }
|
||||
return allCoinNetwork
|
||||
}
|
||||
|
||||
|
|
@ -103,7 +104,7 @@ internal class WcNetworksConverter @Inject constructor(
|
|||
?: return@mapNotNullTo null
|
||||
portfolioNetworks
|
||||
// find all derivation
|
||||
.filter { it.rawId == blockchain.id }
|
||||
.filter { it.rawId == blockchain.toNetworkId() }
|
||||
// find equal address
|
||||
.firstOrNull { network ->
|
||||
val walletAddress = getAddressForWC(wallet.walletId, network)
|
||||
|
|
|
|||
|
|
@ -29,13 +29,14 @@ import com.tangem.blockchain.yieldsupply.providers.YieldSupplyStatus as SDKYield
|
|||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
class DefaultYieldSupplyTransactionRepositoryTest {
|
||||
|
||||
private val networkId = Network.ID(value = "ETH/test", derivationPath = Network.DerivationPath.None)
|
||||
private val networkId = Network.ID(value = "ethereum/test", derivationPath = Network.DerivationPath.None)
|
||||
private val mockedContractAddress = "0x000000000000000000000000000000000000"
|
||||
private val yieldContractAddress = "0x1234"
|
||||
|
||||
private val userWalletId = mockk<UserWalletId>()
|
||||
private val cryptoCurrency = mockk<CryptoCurrency.Token>(relaxed = true) {
|
||||
every { network.id } returns networkId
|
||||
every { network.backendId } returns networkId.rawId.value
|
||||
every { contractAddress } returns mockedContractAddress
|
||||
}
|
||||
private val cryptoCurrencyStatus = mockk<CryptoCurrencyStatus>(relaxed = true) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.domain.account.status.utils
|
||||
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchainsdk.utils.toBlockchain
|
||||
import com.tangem.domain.account.models.AccountList
|
||||
import com.tangem.domain.account.models.AccountStatusList
|
||||
import com.tangem.domain.account.status.model.AccountCryptoCurrency
|
||||
|
|
@ -180,7 +180,7 @@ internal object AccountCryptoCurrencyStatusFinder {
|
|||
contractAddress: String?,
|
||||
): AccountCryptoCurrency? {
|
||||
return accountList.getExpectedAccounts(
|
||||
rawNetworkId = networkId.rawId.value,
|
||||
rawNetworkId = networkId.rawId,
|
||||
derivationPath = derivationPath,
|
||||
)
|
||||
.asSequence()
|
||||
|
|
@ -220,7 +220,7 @@ internal object AccountCryptoCurrencyStatusFinder {
|
|||
|
||||
internal fun AccountStatusList.getExpectedAccountStatuses(networkId: Network.ID): List<AccountStatus> {
|
||||
val possibleAccountIndex = getAccountIndexOrNull(
|
||||
rawNetworkId = networkId.rawId.value,
|
||||
rawNetworkId = networkId.rawId,
|
||||
derivationPath = networkId.derivationPath,
|
||||
)
|
||||
|
||||
|
|
@ -239,7 +239,7 @@ internal object AccountCryptoCurrencyStatusFinder {
|
|||
}
|
||||
|
||||
internal fun AccountStatusList.getExpectedAccountStatuses(networks: List<Network>): List<AccountStatus> {
|
||||
val possibleAccountIndexes = networks.mapNotNull { getAccountIndexOrNull(it.rawId, it.derivationPath) }
|
||||
val possibleAccountIndexes = networks.mapNotNull { getAccountIndexOrNull(it.id.rawId, it.derivationPath) }
|
||||
|
||||
if (possibleAccountIndexes.isEmpty()) return accountStatuses
|
||||
|
||||
|
|
@ -256,16 +256,14 @@ internal object AccountCryptoCurrencyStatusFinder {
|
|||
// region AccountList helpers
|
||||
|
||||
internal fun AccountList.getExpectedAccounts(network: Network?): List<Account> {
|
||||
return getExpectedAccounts(rawNetworkId = network?.rawId, derivationPath = network?.derivationPath)
|
||||
return getExpectedAccounts(rawNetworkId = network?.id?.rawId, derivationPath = network?.derivationPath)
|
||||
}
|
||||
|
||||
private fun AccountList.getExpectedAccounts(
|
||||
rawNetworkId: String?,
|
||||
rawNetworkId: Network.RawID?,
|
||||
derivationPath: Network.DerivationPath?,
|
||||
): List<Account> {
|
||||
val possibleAccountIndex = getAccountIndexOrNull(rawNetworkId, derivationPath)
|
||||
|
||||
return when (possibleAccountIndex) {
|
||||
return when (val possibleAccountIndex = getAccountIndexOrNull(rawNetworkId, derivationPath)) {
|
||||
null -> accounts
|
||||
DerivationIndex.Main.value -> listOf(mainAccount)
|
||||
// currency only in the account with specific derivation index or in the main account
|
||||
|
|
@ -283,10 +281,10 @@ internal object AccountCryptoCurrencyStatusFinder {
|
|||
|
||||
// region Common helpers
|
||||
|
||||
private fun getAccountIndexOrNull(rawNetworkId: String?, derivationPath: Network.DerivationPath?): Int? {
|
||||
private fun getAccountIndexOrNull(rawNetworkId: Network.RawID?, derivationPath: Network.DerivationPath?): Int? {
|
||||
if (rawNetworkId == null || derivationPath == null) return null
|
||||
|
||||
val blockchain = Blockchain.fromId(id = rawNetworkId)
|
||||
val blockchain = rawNetworkId.toBlockchain()
|
||||
val recognizer = AccountNodeRecognizer(blockchain)
|
||||
|
||||
return recognizer.recognize(derivationPath)?.toInt()
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import kotlinx.serialization.Serializable
|
|||
* (e.g., ERC20, BEP20).
|
||||
*
|
||||
* @property id the unique identifier of the network
|
||||
* @property backendId the name of this network in the Tangem backend
|
||||
* @property name the human-readable name of the network, such as "Ethereum" or "Bitcoin"
|
||||
* @property currencySymbol the symbol of the currency associated with the network
|
||||
* @property derivationPath the path used to derive keys for this network
|
||||
|
|
@ -25,7 +24,6 @@ import kotlinx.serialization.Serializable
|
|||
@Serializable
|
||||
data class Network(
|
||||
val id: ID,
|
||||
val backendId: String,
|
||||
val name: String,
|
||||
val currencySymbol: String,
|
||||
val derivationPath: DerivationPath,
|
||||
|
|
@ -37,6 +35,11 @@ data class Network(
|
|||
val nameResolvingType: NameResolvingType,
|
||||
) {
|
||||
|
||||
/** Backend ID */
|
||||
@Deprecated("Will be removed later")
|
||||
val backendId: String
|
||||
get() = id.rawId.value
|
||||
|
||||
/** Raw ID */
|
||||
val rawId: String
|
||||
get() = id.rawId.value
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ sealed interface StakingIntegrationID {
|
|||
* @return a [StakingIntegrationID] if supported, or `null` if not supported.
|
||||
*/
|
||||
fun create(currencyId: CryptoCurrency.ID): StakingIntegrationID? {
|
||||
val blockchain = Blockchain.fromId(id = currencyId.rawNetworkId)
|
||||
val blockchain = currencyId.toBlockchain()
|
||||
|
||||
return if (currencyId.contractAddress.isNullOrBlank()) {
|
||||
// Order is not important — either P2PEthPool or Stakekit.Coin can be in any order
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import arrow.core.left
|
|||
import arrow.core.right
|
||||
import com.google.common.truth.Truth
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchainsdk.utils.toNetworkId
|
||||
import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.staking.StakingID
|
||||
|
|
@ -13,11 +14,7 @@ import com.tangem.domain.staking.model.StakingIntegrationID
|
|||
import com.tangem.domain.staking.toggles.StakingFeatureToggles
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
import com.tangem.test.core.ProvideTestModels
|
||||
import io.mockk.clearMocks
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.coVerify
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.*
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Nested
|
||||
|
|
@ -188,7 +185,7 @@ internal class StakingIdFactoryTest {
|
|||
),
|
||||
CreateModel(
|
||||
currencyId = CryptoCurrency.ID.fromValue(
|
||||
value = "token⟨ETH⟩polygon-ecosystem-token⚓0x7d1afa7b718fb893db30a3abc0cfc608aacfebb0",
|
||||
value = "token⟨ethereum⟩polygon-ecosystem-token⚓0x7d1afa7b718fb893db30a3abc0cfc608aacfebb0",
|
||||
),
|
||||
expected = createStakingId(integrationId = StakingIntegrationID.StakeKit.EthereumToken.Polygon),
|
||||
),
|
||||
|
|
@ -202,6 +199,6 @@ internal class StakingIdFactoryTest {
|
|||
data class CreateModel(val currencyId: CryptoCurrency.ID, val expected: Either<StakingIdFactory.Error, StakingID>)
|
||||
|
||||
private fun createCurrencyId(blockchain: Blockchain): CryptoCurrency.ID {
|
||||
return CryptoCurrency.ID.fromValue(value = "coin⟨${blockchain.id}⟩")
|
||||
return CryptoCurrency.ID.fromValue(value = "coin⟨${blockchain.toNetworkId()}⟩")
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ package com.tangem.domain.staking
|
|||
|
||||
import com.google.common.truth.Truth
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchainsdk.utils.toNetworkId
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.staking.model.StakingApproval
|
||||
import com.tangem.domain.staking.model.StakingIntegrationID
|
||||
|
|
@ -144,11 +145,11 @@ class StakingIntegrationIDTest {
|
|||
expected = StakingIntegrationID.P2PEthPool,
|
||||
),
|
||||
CreateModel(
|
||||
currencyId = CryptoCurrency.ID.fromValue(value = "token⟨ETH⟩polygon-ecosystem-token⚓1234567890"),
|
||||
currencyId = CryptoCurrency.ID.fromValue(value = "token⟨ethereum⟩polygon-ecosystem-token⚓1234567890"),
|
||||
expected = StakingIntegrationID.StakeKit.EthereumToken.Polygon,
|
||||
),
|
||||
CreateModel(
|
||||
currencyId = CryptoCurrency.ID.fromValue(value = "token⟨SOLANA⟩solana⚓1234567890"),
|
||||
currencyId = CryptoCurrency.ID.fromValue(value = "token⟨solana⟩solana⚓1234567890"),
|
||||
expected = null,
|
||||
),
|
||||
)
|
||||
|
|
@ -157,6 +158,6 @@ class StakingIntegrationIDTest {
|
|||
data class CreateModel(val currencyId: CryptoCurrency.ID, val expected: StakingIntegrationID?)
|
||||
|
||||
private fun createCurrencyId(blockchain: Blockchain): CryptoCurrency.ID {
|
||||
return CryptoCurrency.ID.fromValue(value = "coin⟨${blockchain.id}⟩")
|
||||
return CryptoCurrency.ID.fromValue(value = "coin⟨${blockchain.toNetworkId()}⟩")
|
||||
}
|
||||
}
|
||||
|
|
@ -18,7 +18,6 @@ internal object MockNetworks {
|
|||
name = "Network One",
|
||||
isTestnet = false,
|
||||
standardType = Network.StandardType.ERC20,
|
||||
backendId = "network1",
|
||||
currencySymbol = "ETH",
|
||||
derivationPath = Network.DerivationPath.None,
|
||||
hasFiatFeeRate = true,
|
||||
|
|
@ -32,7 +31,6 @@ internal object MockNetworks {
|
|||
name = "Network Two",
|
||||
isTestnet = false,
|
||||
standardType = Network.StandardType.ERC20,
|
||||
backendId = "network1",
|
||||
currencySymbol = "ETH",
|
||||
derivationPath = Network.DerivationPath.None,
|
||||
hasFiatFeeRate = true,
|
||||
|
|
@ -46,7 +44,6 @@ internal object MockNetworks {
|
|||
name = "Network Three",
|
||||
isTestnet = false,
|
||||
standardType = Network.StandardType.ERC20,
|
||||
backendId = "network1",
|
||||
currencySymbol = "ETH",
|
||||
derivationPath = Network.DerivationPath.None,
|
||||
hasFiatFeeRate = true,
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ dependencies {
|
|||
/** Core */
|
||||
implementation(projects.core.ui)
|
||||
implementation(projects.core.utils)
|
||||
implementation(projects.libs.blockchainSdk)
|
||||
|
||||
/** Domain */
|
||||
implementation(projects.domain.account.status)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import arrow.core.Either.Companion.catch
|
|||
import arrow.core.getOrElse
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.transaction.Fee
|
||||
import com.tangem.blockchainsdk.utils.toNetworkId
|
||||
import com.tangem.domain.account.status.utils.CryptoCurrencyOperations.getCoin
|
||||
import com.tangem.domain.account.supplier.SingleAccountListSupplier
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
|
|
@ -67,8 +68,7 @@ class YieldSupplyGetCurrentFeeUseCase(
|
|||
|
||||
val tokenValue = rateRatio.multiply(nativeGas.amount.value)
|
||||
|
||||
val isEthereum = cryptoCurrencyStatus.currency
|
||||
.network.id.rawId.value == Blockchain.Ethereum.id
|
||||
val isEthereum = cryptoCurrencyStatus.currency.network.rawId == Blockchain.Ethereum.toNetworkId()
|
||||
|
||||
val isHighFee = if (isEthereum) {
|
||||
val maxFeePerGas = (feeWithoutGas as? Fee.Ethereum.EIP1559)?.maxFeePerGas ?: 0.toBigInteger()
|
||||
|
|
|
|||
|
|
@ -165,8 +165,7 @@ class YieldSupplyMinAmountUseCaseTest {
|
|||
private fun createNetwork(): Network {
|
||||
val derivationPath = Network.DerivationPath.None
|
||||
return Network(
|
||||
id = Network.ID(Network.RawID("polygon"), derivationPath),
|
||||
backendId = "polygon",
|
||||
id = Network.ID(value = "polygon", derivationPath = derivationPath),
|
||||
name = "Polygon",
|
||||
currencySymbol = "MATIC",
|
||||
derivationPath = derivationPath,
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
|||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.network.NetworkAddress
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.yield.supply.YieldSupplyRepository
|
||||
import com.tangem.domain.models.yield.supply.YieldSupplyStatus
|
||||
import com.tangem.domain.yield.supply.YieldSupplyRepository
|
||||
import com.tangem.domain.yield.supply.models.YieldSupplyPendingStatus
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.coVerify
|
||||
|
|
@ -324,7 +324,6 @@ class YieldSupplyEnterStatusUseCaseTest {
|
|||
val derivationPath = Network.DerivationPath.None
|
||||
val network = Network(
|
||||
id = Network.ID(value = rawNetworkId, derivationPath = derivationPath),
|
||||
backendId = rawNetworkId,
|
||||
name = rawNetworkId,
|
||||
currencySymbol = rawNetworkId.take(3).uppercase(),
|
||||
derivationPath = derivationPath,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ package com.tangem.domain.yield.supply.usecase
|
|||
|
||||
import arrow.core.Either
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
|
||||
import com.tangem.blockchain.common.transaction.Fee
|
||||
import com.tangem.domain.account.models.AccountList
|
||||
import com.tangem.domain.account.supplier.SingleAccountListSupplier
|
||||
|
|
@ -48,7 +48,7 @@ class YieldSupplyGetCurrentFeeUseCaseTest {
|
|||
|
||||
@Test
|
||||
fun `GIVEN valid inputs on non-ethereum WHEN invoke THEN returns fee value and not high`() = runTest {
|
||||
val rawNetworkId = Blockchain.BSC.id
|
||||
val rawNetworkId = "binance-smart-chain"
|
||||
val tokenDecimals = 8
|
||||
val nativeDecimals = 18
|
||||
val token = createToken(rawNetworkId = rawNetworkId, decimals = tokenDecimals)
|
||||
|
|
@ -100,7 +100,7 @@ class YieldSupplyGetCurrentFeeUseCaseTest {
|
|||
|
||||
@Test
|
||||
fun `GIVEN ethereum with high gas WHEN invoke THEN returns high fee flag`() = runTest {
|
||||
val rawNetworkId = Blockchain.Ethereum.id
|
||||
val rawNetworkId = "ethereum"
|
||||
val tokenDecimals = 8
|
||||
val nativeDecimals = 18
|
||||
val token = createToken(rawNetworkId = rawNetworkId, decimals = tokenDecimals)
|
||||
|
|
@ -152,7 +152,7 @@ class YieldSupplyGetCurrentFeeUseCaseTest {
|
|||
|
||||
@Test
|
||||
fun `GIVEN token fiat rate missing WHEN invoke THEN returns error`() = runTest {
|
||||
val rawNetworkId = Blockchain.BSC.id
|
||||
val rawNetworkId = "binance-smart-chain"
|
||||
val token = createToken(rawNetworkId = rawNetworkId, decimals = 8)
|
||||
val cryptoStatus = createStatus(token = token, fiatRate = null)
|
||||
|
||||
|
|
@ -175,7 +175,7 @@ class YieldSupplyGetCurrentFeeUseCaseTest {
|
|||
|
||||
@Test
|
||||
fun `GIVEN native quotes unavailable WHEN invoke THEN returns error`() = runTest {
|
||||
val rawNetworkId = Blockchain.BSC.id
|
||||
val rawNetworkId = "binance-smart-chain"
|
||||
val token = createToken(rawNetworkId = rawNetworkId, decimals = 8)
|
||||
val cryptoStatus = createStatus(token = token, fiatRate = BigDecimal("2.00"))
|
||||
val nativeCoin = createCoin(rawNetworkId = rawNetworkId, decimals = 18)
|
||||
|
|
@ -204,7 +204,7 @@ class YieldSupplyGetCurrentFeeUseCaseTest {
|
|||
|
||||
@Test
|
||||
fun `GIVEN empty quotes list WHEN invoke THEN returns error`() = runTest {
|
||||
val rawNetworkId = Blockchain.BSC.id
|
||||
val rawNetworkId = "binance-smart-chain"
|
||||
val token = createToken(rawNetworkId = rawNetworkId, decimals = 8)
|
||||
val cryptoStatus = createStatus(token = token, fiatRate = BigDecimal("2.00"))
|
||||
val nativeCoin = createCoin(rawNetworkId = rawNetworkId, decimals = 18)
|
||||
|
|
@ -233,7 +233,7 @@ class YieldSupplyGetCurrentFeeUseCaseTest {
|
|||
|
||||
@Test
|
||||
fun `GIVEN native fiat rate non-positive WHEN invoke THEN returns error`() = runTest {
|
||||
val rawNetworkId = Blockchain.BSC.id
|
||||
val rawNetworkId = "binance-smart-chain"
|
||||
val token = createToken(rawNetworkId = rawNetworkId, decimals = 8)
|
||||
val cryptoStatus = createStatus(token = token, fiatRate = BigDecimal("2.00"))
|
||||
val nativeCoin = createCoin(rawNetworkId = rawNetworkId, decimals = 18)
|
||||
|
|
@ -274,7 +274,7 @@ class YieldSupplyGetCurrentFeeUseCaseTest {
|
|||
|
||||
@Test
|
||||
fun `GIVEN token fiat rate non-positive WHEN invoke THEN returns error`() = runTest {
|
||||
val rawNetworkId = Blockchain.BSC.id
|
||||
val rawNetworkId = "binance-smart-chain"
|
||||
val token = createToken(rawNetworkId = rawNetworkId, decimals = 8)
|
||||
val cryptoStatus = createStatus(token = token, fiatRate = BigDecimal.ZERO) // non-positive
|
||||
|
||||
|
|
@ -299,7 +299,6 @@ class YieldSupplyGetCurrentFeeUseCaseTest {
|
|||
val derivationPath = Network.DerivationPath.None
|
||||
val network = Network(
|
||||
id = Network.ID(value = rawNetworkId, derivationPath = derivationPath),
|
||||
backendId = rawNetworkId,
|
||||
name = rawNetworkId,
|
||||
currencySymbol = rawNetworkId.take(3).uppercase(),
|
||||
derivationPath = derivationPath,
|
||||
|
|
@ -331,7 +330,6 @@ class YieldSupplyGetCurrentFeeUseCaseTest {
|
|||
val derivationPath = Network.DerivationPath.None
|
||||
val network = Network(
|
||||
id = Network.ID(value = rawNetworkId, derivationPath = derivationPath),
|
||||
backendId = rawNetworkId,
|
||||
name = rawNetworkId,
|
||||
currencySymbol = rawNetworkId.take(3).uppercase(),
|
||||
derivationPath = derivationPath,
|
||||
|
|
|
|||
|
|
@ -61,8 +61,7 @@ class YieldSupplyGetDustMinAmountUseCaseTest {
|
|||
private fun createNetwork(): Network {
|
||||
val derivationPath = Network.DerivationPath.None
|
||||
return Network(
|
||||
id = Network.ID(Network.RawID("polygon"), derivationPath),
|
||||
backendId = "polygon",
|
||||
id = Network.ID(value = "polygon", derivationPath = derivationPath),
|
||||
name = "Polygon",
|
||||
currencySymbol = "MATIC",
|
||||
derivationPath = derivationPath,
|
||||
|
|
|
|||
|
|
@ -238,8 +238,7 @@ class YieldSupplyGetRewardsBalanceUseCaseTest {
|
|||
@Test
|
||||
fun `GIVEN polygon USDT0 Loaded status WHEN invoke THEN emit formatted balances`() = runTest {
|
||||
val network = Network(
|
||||
id = Network.ID(Network.RawID("POLYGON"), Network.DerivationPath.Card("m/44'/60'/0'/0/0")),
|
||||
backendId = "polygon-pos",
|
||||
id = Network.ID(value = "polygon-pos", derivationPath = Network.DerivationPath.Card("m/44'/60'/0'/0/0")),
|
||||
name = "Polygon",
|
||||
currencySymbol = "POL",
|
||||
derivationPath = Network.DerivationPath.Card("m/44'/60'/0'/0/0"),
|
||||
|
|
@ -365,8 +364,7 @@ class YieldSupplyGetRewardsBalanceUseCaseTest {
|
|||
private fun createNetwork(): Network {
|
||||
val derivationPath = Network.DerivationPath.None
|
||||
return Network(
|
||||
id = Network.ID(Network.RawID("polygon"), derivationPath),
|
||||
backendId = "polygon",
|
||||
id = Network.ID(value = "polygon", derivationPath = derivationPath),
|
||||
name = "Polygon",
|
||||
currencySymbol = "MATIC",
|
||||
derivationPath = derivationPath,
|
||||
|
|
|
|||
|
|
@ -279,7 +279,6 @@ class YieldSupplyPendingTrackerTest {
|
|||
val derivationPath = Network.DerivationPath.None
|
||||
val network = Network(
|
||||
id = Network.ID(value = networkId, derivationPath = derivationPath),
|
||||
backendId = networkId,
|
||||
name = networkId,
|
||||
currencySymbol = networkId.take(3).uppercase(),
|
||||
derivationPath = derivationPath,
|
||||
|
|
|
|||
|
|
@ -57,7 +57,6 @@ internal class PreviewCustomTokenSelectorComponent(
|
|||
CurrencyNetworkUM(
|
||||
network = Network(
|
||||
id = n.id,
|
||||
backendId = n.id.rawId.value,
|
||||
name = "Network $index",
|
||||
currencySymbol = "N$index",
|
||||
derivationPath = Network.DerivationPath.Card(""),
|
||||
|
|
|
|||
|
|
@ -154,7 +154,6 @@ internal class PreviewManageTokensComponent(
|
|||
CurrencyNetworkUM(
|
||||
network = Network(
|
||||
id = Network.ID(value = networkIndex.toString(), derivationPath = derivationPath),
|
||||
backendId = networkIndex.toString(),
|
||||
name = "Network $networkIndex",
|
||||
currencySymbol = "N$networkIndex",
|
||||
derivationPath = derivationPath,
|
||||
|
|
|
|||
|
|
@ -95,7 +95,6 @@ internal class PreviewOnboardingManageTokensComponent(
|
|||
CurrencyNetworkUM(
|
||||
network = Network(
|
||||
id = Network.ID(value = networkIndex.toString(), derivationPath = derivationPath),
|
||||
backendId = networkIndex.toString(),
|
||||
name = "Network $networkIndex",
|
||||
currencySymbol = "N$networkIndex",
|
||||
derivationPath = derivationPath,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package com.tangem.features.managetokens.model
|
|||
import arrow.core.getOrElse
|
||||
import com.arkivanov.decompose.router.slot.SlotNavigation
|
||||
import com.arkivanov.decompose.router.slot.activate
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchainsdk.utils.toBlockchain
|
||||
import com.tangem.common.ui.account.toUM
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.model.Model
|
||||
|
|
@ -199,7 +199,7 @@ internal class CustomTokenSelectorModel @Inject constructor(
|
|||
private fun DerivationPathSelector.checkAccountDerivation(derivationPath: SelectedDerivationPath) =
|
||||
modelScope.launch {
|
||||
val account = derivationPath.id
|
||||
?.let { Blockchain.fromId(it.rawId.value) }
|
||||
?.toBlockchain()
|
||||
?.let(::AccountNodeRecognizer)
|
||||
?.let { recognizer ->
|
||||
val derivationPathValue = derivationPath.value.value
|
||||
|
|
|
|||
|
|
@ -133,7 +133,6 @@ private fun Preview() {
|
|||
value = "bitcoin",
|
||||
derivationPath = Network.DerivationPath.None,
|
||||
),
|
||||
backendId = "bitcoin",
|
||||
name = "Bitcoin",
|
||||
currencySymbol = "BTC",
|
||||
derivationPath = Network.DerivationPath.None,
|
||||
|
|
|
|||
|
|
@ -516,7 +516,6 @@ private val cryptoCurrencyStatus
|
|||
value = "bitcoin",
|
||||
derivationPath = Network.DerivationPath.None,
|
||||
),
|
||||
backendId = "bitcoin",
|
||||
name = "Bitcoin",
|
||||
currencySymbol = "BTC",
|
||||
derivationPath = Network.DerivationPath.None,
|
||||
|
|
|
|||
|
|
@ -171,7 +171,6 @@ private fun Preview() {
|
|||
value = "bitcoin",
|
||||
derivationPath = Network.DerivationPath.None,
|
||||
),
|
||||
backendId = "bitcoin",
|
||||
name = "Bitcoin",
|
||||
currencySymbol = "BTC",
|
||||
derivationPath = Network.DerivationPath.None,
|
||||
|
|
|
|||
|
|
@ -258,7 +258,6 @@ private class FeeSelectorUMProvider : PreviewParameterProvider<FeeSelectorUM> {
|
|||
value = "bitcoin",
|
||||
derivationPath = Network.DerivationPath.None,
|
||||
),
|
||||
backendId = "bitcoin",
|
||||
name = "Bitcoin",
|
||||
currencySymbol = "BTC",
|
||||
derivationPath = Network.DerivationPath.None,
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ class NFTSendConfirmationNotificationsTransformerV2Test {
|
|||
private val appCurrency = AppCurrency(name = "US Dollar", code = "USD", symbol = "$")
|
||||
private val analyticsCategoryName = "test_category"
|
||||
|
||||
val cryptoCurrencyStatus = CryptoCurrencyStatus(
|
||||
private val cryptoCurrencyStatus = CryptoCurrencyStatus(
|
||||
currency = CryptoCurrency.Coin(
|
||||
id = CryptoCurrency.ID.fromValue("coin⟨BITCOIN⟩bitcoin"),
|
||||
network = Network(
|
||||
|
|
@ -38,7 +38,6 @@ class NFTSendConfirmationNotificationsTransformerV2Test {
|
|||
value = "bitcoin",
|
||||
derivationPath = Network.DerivationPath.None,
|
||||
),
|
||||
backendId = "bitcoin",
|
||||
name = "Bitcoin",
|
||||
currencySymbol = "BTC",
|
||||
derivationPath = Network.DerivationPath.None,
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ class SendConfirmationNotificationsTransformerV2Test {
|
|||
private val appCurrency = AppCurrency(name = "US Dollar", code = "USD", symbol = "$")
|
||||
private val analyticsCategoryName = "test_category"
|
||||
|
||||
val cryptoCurrencyStatus = CryptoCurrencyStatus(
|
||||
private val cryptoCurrencyStatus = CryptoCurrencyStatus(
|
||||
currency = CryptoCurrency.Coin(
|
||||
id = CryptoCurrency.ID.fromValue("coin⟨BITCOIN⟩bitcoin"),
|
||||
network = Network(
|
||||
|
|
@ -40,7 +40,6 @@ class SendConfirmationNotificationsTransformerV2Test {
|
|||
value = "bitcoin",
|
||||
derivationPath = Network.DerivationPath.None,
|
||||
),
|
||||
backendId = "bitcoin",
|
||||
name = "Bitcoin",
|
||||
currencySymbol = "BTC",
|
||||
derivationPath = Network.DerivationPath.None,
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ internal data object SwapAmountContentPreview {
|
|||
value = "bitcoin",
|
||||
derivationPath = Network.DerivationPath.None,
|
||||
),
|
||||
backendId = "bitcoin",
|
||||
name = "Bitcoin",
|
||||
currencySymbol = "BTC",
|
||||
derivationPath = Network.DerivationPath.None,
|
||||
|
|
|
|||
|
|
@ -104,7 +104,6 @@ class ExpressStatusBottomSheetStateProvider : PreviewParameterProvider<ExpressSt
|
|||
name = "Network One",
|
||||
isTestnet = false,
|
||||
standardType = Network.StandardType.ERC20,
|
||||
backendId = "network1",
|
||||
currencySymbol = "ETH",
|
||||
derivationPath = Network.DerivationPath.None,
|
||||
hasFiatFeeRate = true,
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ class YieldSupplyPromoBannerConverterTest {
|
|||
|
||||
@Test
|
||||
fun `GIVEN promo disabled WHEN convert THEN return null`() {
|
||||
val token = createToken(networkId = "ethereum", backendId = "ethereum", contract = "0xABCDEF")
|
||||
val token = createToken(networkId = "ethereum", rawId = "ethereum", contract = "0xABCDEF")
|
||||
val status = createLoadedStatus(token = token, amount = BigDecimal.ONE, isYieldActive = false)
|
||||
val tokenList = ungroupedTokenList(status)
|
||||
val params = TokenConverterParams.Wallet(
|
||||
|
|
@ -46,7 +46,7 @@ class YieldSupplyPromoBannerConverterTest {
|
|||
|
||||
@Test
|
||||
fun `GIVEN empty apy map WHEN convert THEN return null`() {
|
||||
val token = createToken(networkId = "ethereum", backendId = "ethereum", contract = "0xA1")
|
||||
val token = createToken(networkId = "ethereum", rawId = "ethereum", contract = "0xA1")
|
||||
val status = createLoadedStatus(token = token, amount = BigDecimal("2.0"), isYieldActive = false)
|
||||
val params = TokenConverterParams.Wallet(
|
||||
mainAccount = account,
|
||||
|
|
@ -64,7 +64,7 @@ class YieldSupplyPromoBannerConverterTest {
|
|||
|
||||
@Test
|
||||
fun `GIVEN active yield token present WHEN convert THEN return null`() {
|
||||
val token = createToken(networkId = "ethereum", backendId = "ethereum", contract = "0xAA")
|
||||
val token = createToken(networkId = "ethereum", rawId = "ethereum", contract = "0xAA")
|
||||
val statusActive = createLoadedStatus(token = token, amount = BigDecimal("5"), isYieldActive = true)
|
||||
val params = TokenConverterParams.Wallet(
|
||||
mainAccount = account,
|
||||
|
|
@ -82,9 +82,9 @@ class YieldSupplyPromoBannerConverterTest {
|
|||
|
||||
@Test
|
||||
fun `GIVEN multiple candidates EVM case insensitive WHEN convert THEN return status of max amount`() {
|
||||
val evmNetworkId = "ETH"
|
||||
val tokenSmall = createToken(networkId = evmNetworkId, backendId = evmNetworkId, contract = "0xAbCd")
|
||||
val tokenBig = createToken(networkId = evmNetworkId, backendId = evmNetworkId, contract = "0xBEEF")
|
||||
val evmNetworkId = "ethereum"
|
||||
val tokenSmall = createToken(networkId = evmNetworkId, rawId = evmNetworkId, contract = "0xAbCd")
|
||||
val tokenBig = createToken(networkId = evmNetworkId, rawId = evmNetworkId, contract = "0xBEEF")
|
||||
|
||||
val statusSmall = createLoadedStatus(token = tokenSmall, amount = BigDecimal("1.00"), isYieldActive = false)
|
||||
val statusBig = createLoadedStatus(token = tokenBig, amount = BigDecimal("10.00"), isYieldActive = false)
|
||||
|
|
@ -111,7 +111,7 @@ class YieldSupplyPromoBannerConverterTest {
|
|||
@Test
|
||||
fun `GIVEN non evm case sensitive mismatch WHEN convert THEN return null`() {
|
||||
val nonEvmId = "xrp"
|
||||
val token = createToken(networkId = nonEvmId, backendId = nonEvmId, contract = "rAbC123")
|
||||
val token = createToken(networkId = nonEvmId, rawId = nonEvmId, contract = "rAbC123")
|
||||
val status = createLoadedStatus(token = token, amount = BigDecimal("3"), isYieldActive = false)
|
||||
|
||||
val mismatchedKey = "${token.network.backendId}_${token.contractAddress.lowercase()}"
|
||||
|
|
@ -133,7 +133,7 @@ class YieldSupplyPromoBannerConverterTest {
|
|||
|
||||
@Test
|
||||
fun `GIVEN custom status WHEN convert THEN return null`() {
|
||||
val token = createToken(networkId = "ethereum", backendId = "ethereum", contract = "0xCUSTOM")
|
||||
val token = createToken(networkId = "ethereum", rawId = "ethereum", contract = "0xCUSTOM")
|
||||
val status = createCustomStatus(token = token, amount = BigDecimal("5.0"), isYieldActive = false)
|
||||
val params = TokenConverterParams.Wallet(
|
||||
mainAccount = account,
|
||||
|
|
@ -236,15 +236,14 @@ class YieldSupplyPromoBannerConverterTest {
|
|||
)
|
||||
}
|
||||
|
||||
private fun createToken(networkId: String, backendId: String, contract: String): CryptoCurrency.Token {
|
||||
private fun createToken(networkId: String, rawId: String, contract: String): CryptoCurrency.Token {
|
||||
val network = Network(
|
||||
id = Network.ID(value = networkId, derivationPath = Network.DerivationPath.None),
|
||||
backendId = backendId,
|
||||
name = backendId,
|
||||
id = Network.ID(value = rawId, derivationPath = Network.DerivationPath.None),
|
||||
name = rawId,
|
||||
currencySymbol = "SYM",
|
||||
derivationPath = Network.DerivationPath.None,
|
||||
isTestnet = false,
|
||||
standardType = when (backendId) {
|
||||
standardType = when (rawId) {
|
||||
"ethereum" -> Network.StandardType.ERC20
|
||||
else -> Network.StandardType.Unspecified("UNSPEC")
|
||||
},
|
||||
|
|
|
|||
|
|
@ -834,10 +834,9 @@ class DefaultPromoDeeplinkHandlerTest {
|
|||
address: String,
|
||||
derivationPath: Network.DerivationPath = Network.DerivationPath.None,
|
||||
): NetworkStatus {
|
||||
val networkId = Network.ID(Network.RawID(rawNetworkId), derivationPath)
|
||||
val networkId = Network.ID(value = rawNetworkId, derivationPath = derivationPath)
|
||||
val network = Network(
|
||||
id = networkId,
|
||||
backendId = rawNetworkId,
|
||||
name = rawNetworkId,
|
||||
currencySymbol = rawNetworkId.take(3).uppercase(),
|
||||
derivationPath = derivationPath,
|
||||
|
|
@ -866,10 +865,9 @@ class DefaultPromoDeeplinkHandlerTest {
|
|||
}
|
||||
|
||||
private fun buildUnreachableNetworkStatus(rawNetworkId: String): NetworkStatus {
|
||||
val networkId = Network.ID(Network.RawID(rawNetworkId), Network.DerivationPath.None)
|
||||
val networkId = Network.ID(value = rawNetworkId, derivationPath = Network.DerivationPath.None)
|
||||
val network = Network(
|
||||
id = networkId,
|
||||
backendId = rawNetworkId,
|
||||
name = rawNetworkId,
|
||||
currencySymbol = rawNetworkId.take(3).uppercase(),
|
||||
derivationPath = Network.DerivationPath.None,
|
||||
|
|
@ -890,10 +888,9 @@ class DefaultPromoDeeplinkHandlerTest {
|
|||
rawNetworkId: String,
|
||||
derivationPath: Network.DerivationPath = Network.DerivationPath.None,
|
||||
): CryptoCurrency.Coin {
|
||||
val networkId = Network.ID(Network.RawID(rawNetworkId), derivationPath)
|
||||
val networkId = Network.ID(value = rawNetworkId, derivationPath = derivationPath)
|
||||
val network = Network(
|
||||
id = networkId,
|
||||
backendId = rawNetworkId,
|
||||
name = rawNetworkId,
|
||||
currencySymbol = rawNetworkId.take(3).uppercase(),
|
||||
derivationPath = derivationPath,
|
||||
|
|
|
|||
|
|
@ -285,8 +285,7 @@ internal class QrContentClassifierTest {
|
|||
|
||||
private fun buildNetwork(rawNetworkId: String): Network {
|
||||
return Network(
|
||||
id = Network.ID(Network.RawID(rawNetworkId), Network.DerivationPath.None),
|
||||
backendId = rawNetworkId,
|
||||
id = Network.ID(value = rawNetworkId, derivationPath = Network.DerivationPath.None),
|
||||
name = rawNetworkId,
|
||||
currencySymbol = rawNetworkId.take(3).uppercase(),
|
||||
derivationPath = Network.DerivationPath.None,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.blockchainsdk.utils
|
||||
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.network.Network
|
||||
|
||||
/** Converts [Network] to [Blockchain] */
|
||||
|
|
@ -10,4 +11,8 @@ fun Network.toBlockchain(): Blockchain = id.toBlockchain()
|
|||
fun Network.ID.toBlockchain(): Blockchain = rawId.toBlockchain()
|
||||
|
||||
/** Converts [Network.RawID] to [Blockchain] */
|
||||
fun Network.RawID.toBlockchain(): Blockchain = Blockchain.fromId(id = value)
|
||||
fun Network.RawID.toBlockchain(): Blockchain = value.toBlockchain()
|
||||
|
||||
fun CryptoCurrency.ID.toBlockchain(): Blockchain = rawNetworkId.toBlockchain()
|
||||
|
||||
private fun String.toBlockchain(): Blockchain = Blockchain.fromNetworkId(this) ?: Blockchain.Unknown
|
||||
|
|
@ -28,9 +28,9 @@ object BlockchainUtils {
|
|||
|
||||
/** Decodes XRP Blockchain address */
|
||||
fun decodeRippleXAddress(xAddress: String, blockchainId: String): XrpTaggedAddress? {
|
||||
return if (blockchainId == Blockchain.XRP.id && xAddress.firstOrNull() == XRP_X_ADDRESS) {
|
||||
return if (blockchainId.toBlockchain() == Blockchain.XRP && xAddress.firstOrNull() == XRP_X_ADDRESS) {
|
||||
val decodedAddress = XrpAddressService.decodeXAddress(xAddress)
|
||||
return decodedAddress?.let(XrpTaggedAddressConverter()::convert)
|
||||
decodedAddress?.let(XrpTaggedAddressConverter()::convert)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
|
@ -38,46 +38,46 @@ object BlockchainUtils {
|
|||
|
||||
/** If current [networkId] is Bitcoin */
|
||||
fun isBitcoin(blockchainId: String): Boolean {
|
||||
val blockchain = Blockchain.fromId(blockchainId)
|
||||
val blockchain = blockchainId.toBlockchain()
|
||||
return blockchain == Blockchain.Bitcoin || blockchain == Blockchain.BitcoinTestnet
|
||||
}
|
||||
|
||||
/** If current [networkId] is use custom fee */
|
||||
fun isUseBitcoinFeeConverter(blockchainId: String): Boolean {
|
||||
val blockchain = Blockchain.fromId(blockchainId)
|
||||
val blockchain = blockchainId.toBlockchain()
|
||||
return isBitcoin(blockchainId) || blockchain == Blockchain.Fact0rn
|
||||
}
|
||||
|
||||
/** If current [blockchainId] is Tezos */
|
||||
fun isTezos(blockchainId: String): Boolean {
|
||||
val blockchain = Blockchain.fromId(blockchainId)
|
||||
val blockchain = blockchainId.toBlockchain()
|
||||
return blockchain == Blockchain.Tezos
|
||||
}
|
||||
|
||||
fun isCardano(blockchainId: String): Boolean {
|
||||
val blockchain = Blockchain.fromId(blockchainId)
|
||||
val blockchain = blockchainId.toBlockchain()
|
||||
return blockchain == Blockchain.Cardano
|
||||
}
|
||||
|
||||
/** If current [blockchainId] is BeaconChain */
|
||||
fun isBeaconChain(blockchainId: String): Boolean {
|
||||
val blockchain = Blockchain.fromId(blockchainId)
|
||||
val blockchain = blockchainId.toBlockchain()
|
||||
return blockchain == Blockchain.Binance || blockchain == Blockchain.BinanceTestnet
|
||||
}
|
||||
|
||||
/** If current [blockchainId] is Polygon */
|
||||
fun isPolygonChain(blockchainId: String): Boolean {
|
||||
val blockchain = Blockchain.fromId(blockchainId)
|
||||
val blockchain = blockchainId.toBlockchain()
|
||||
return blockchain == Blockchain.Polygon || blockchain == Blockchain.PolygonTestnet
|
||||
}
|
||||
|
||||
fun isTron(blockchainId: String): Boolean {
|
||||
val blockchain = Blockchain.fromId(blockchainId)
|
||||
val blockchain = blockchainId.toBlockchain()
|
||||
return blockchain == Blockchain.Tron || blockchain == Blockchain.TronTestnet
|
||||
}
|
||||
|
||||
fun isTon(blockchainId: String): Boolean {
|
||||
val blockchain = Blockchain.fromId(blockchainId)
|
||||
val blockchain = blockchainId.toBlockchain()
|
||||
return blockchain == Blockchain.TON || blockchain == Blockchain.TONTestnet
|
||||
}
|
||||
|
||||
|
|
@ -89,7 +89,7 @@ object BlockchainUtils {
|
|||
coinId: String? = null,
|
||||
contractAddress: String? = null,
|
||||
): Boolean {
|
||||
val blockchain = Blockchain.fromNetworkId(blockchainId) ?: return false
|
||||
val blockchain = blockchainId.toBlockchain() ?: return false
|
||||
|
||||
if (blockchain in excludedBlockchains) return false
|
||||
if (hasOnlyHotWallets && blockchain in hotExcludedBlockchains) return false
|
||||
|
|
@ -103,37 +103,37 @@ object BlockchainUtils {
|
|||
}
|
||||
|
||||
fun isArbitrum(blockchainId: String): Boolean {
|
||||
val blockchain = Blockchain.fromId(blockchainId)
|
||||
val blockchain = blockchainId.toBlockchain()
|
||||
return blockchain == Blockchain.Arbitrum
|
||||
}
|
||||
|
||||
fun isSolana(blockchainId: String): Boolean {
|
||||
val blockchain = Blockchain.fromId(blockchainId)
|
||||
val blockchain = blockchainId.toBlockchain()
|
||||
return blockchain == Blockchain.Solana
|
||||
}
|
||||
|
||||
fun isPolkadot(blockchainId: String): Boolean {
|
||||
val blockchain = Blockchain.fromId(blockchainId)
|
||||
val blockchain = blockchainId.toBlockchain()
|
||||
return blockchain == Blockchain.Polkadot || blockchain == Blockchain.PolkadotTestnet
|
||||
}
|
||||
|
||||
fun isCosmos(blockchainId: String): Boolean {
|
||||
val blockchain = Blockchain.fromId(blockchainId)
|
||||
val blockchain = blockchainId.toBlockchain()
|
||||
return blockchain == Blockchain.Cosmos || blockchain == Blockchain.CosmosTestnet
|
||||
}
|
||||
|
||||
fun isBSC(blockchainId: String): Boolean {
|
||||
val blockchain = Blockchain.fromId(blockchainId)
|
||||
val blockchain = blockchainId.toBlockchain()
|
||||
return blockchain == Blockchain.BSC || blockchain == Blockchain.BSCTestnet
|
||||
}
|
||||
|
||||
fun isEthereum(blockchainId: String): Boolean {
|
||||
val blockchain = Blockchain.fromId(blockchainId)
|
||||
val blockchain = blockchainId.toBlockchain()
|
||||
return blockchain == Blockchain.Ethereum || blockchain == Blockchain.EthereumTestnet
|
||||
}
|
||||
|
||||
fun isClore(blockchainId: String): Boolean {
|
||||
return Blockchain.fromId(blockchainId) == Blockchain.Clore
|
||||
return blockchainId.toBlockchain() == Blockchain.Clore
|
||||
}
|
||||
|
||||
data class BlockchainInfo(
|
||||
|
|
@ -163,7 +163,7 @@ object BlockchainUtils {
|
|||
* Blockchains not affecting total balance counting on errors
|
||||
*/
|
||||
fun isIncludeToBalanceOnError(blockchainId: String): Boolean {
|
||||
val blockchain = Blockchain.fromId(blockchainId)
|
||||
val blockchain = blockchainId.toBlockchain()
|
||||
return when (blockchain) {
|
||||
Blockchain.Binance, Blockchain.BinanceTestnet -> true
|
||||
else -> false
|
||||
|
|
@ -171,7 +171,7 @@ object BlockchainUtils {
|
|||
}
|
||||
|
||||
fun isIncludeStakingTotalBalance(blockchainId: String): Boolean {
|
||||
val blockchain = Blockchain.fromId(blockchainId)
|
||||
val blockchain = blockchainId.toBlockchain()
|
||||
|
||||
return blockchain != Blockchain.Cardano
|
||||
}
|
||||
|
|
@ -184,9 +184,9 @@ object BlockchainUtils {
|
|||
|
||||
/** Checks if the blockchain uses case-insensitive contract addresses */
|
||||
fun isCaseInsensitiveContractAddress(blockchainId: String): Boolean {
|
||||
val blockchain = Blockchain.fromId(blockchainId)
|
||||
val blockchain = blockchainId.toBlockchain()
|
||||
|
||||
return blockchain.isEvm()
|
||||
return blockchain?.isEvm() == true
|
||||
}
|
||||
|
||||
private fun getNetworkStandardName(blockchain: Blockchain): String {
|
||||
|
|
@ -223,8 +223,10 @@ object BlockchainUtils {
|
|||
* Checks if the given coin is Tether on Ethereum network, which may require special handling in some cases.
|
||||
*/
|
||||
fun isTetherInEthereum(blockchainId: String, contractAddress: String): Boolean {
|
||||
val blockchain = Blockchain.fromId(blockchainId)
|
||||
val blockchain = blockchainId.toBlockchain()
|
||||
return (blockchain == Blockchain.Ethereum || blockchain == Blockchain.EthereumTestnet) &&
|
||||
contractAddress.equals(TETHER_CONTRACT_ADDRESS, ignoreCase = true)
|
||||
}
|
||||
|
||||
private fun String.toBlockchain(): Blockchain? = Blockchain.fromNetworkId(this)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue