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(
|
val network = Network(
|
||||||
id = Network.ID(blockchain.id, derivationPath),
|
id = Network.ID(value = blockchain.toNetworkId(), derivationPath = derivationPath),
|
||||||
backendId = blockchain.toNetworkId(),
|
|
||||||
name = blockchain.fullName,
|
name = blockchain.fullName,
|
||||||
isTestnet = blockchain.isTestnet(),
|
isTestnet = blockchain.isTestnet(),
|
||||||
derivationPath = derivationPath,
|
derivationPath = derivationPath,
|
||||||
|
|
@ -85,12 +84,11 @@ class MockCryptoCurrencyFactory(private val userWallet: UserWallet.Cold = defaul
|
||||||
return CryptoCurrency.Token(
|
return CryptoCurrency.Token(
|
||||||
id = CryptoCurrency.ID(
|
id = CryptoCurrency.ID(
|
||||||
prefix = CryptoCurrency.ID.Prefix.TOKEN_PREFIX,
|
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),
|
suffix = CryptoCurrency.ID.Suffix.RawID(blockchain.id),
|
||||||
),
|
),
|
||||||
network = Network(
|
network = Network(
|
||||||
id = Network.ID(value = blockchain.id, derivationPath),
|
id = Network.ID(value = blockchain.toNetworkId(), derivationPath = derivationPath),
|
||||||
backendId = "NEVER-MIND",
|
|
||||||
name = blockchain.fullName,
|
name = blockchain.fullName,
|
||||||
currencySymbol = "NEVER-MIND",
|
currencySymbol = "NEVER-MIND",
|
||||||
derivationPath = derivationPath,
|
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.PreferencesKeys.SHOULD_SHOW_RING_PROMO_KEY
|
||||||
import com.tangem.datasource.local.preferences.utils.CleanupKeyMigration
|
import com.tangem.datasource.local.preferences.utils.CleanupKeyMigration
|
||||||
import com.tangem.datasource.local.preferences.utils.SharedPreferencesKeyMigration
|
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.coroutines.AppCoroutineScope
|
||||||
import com.tangem.utils.logging.TangemLogger
|
import com.tangem.utils.logging.TangemLogger
|
||||||
|
|
||||||
|
|
@ -80,6 +81,7 @@ internal object PreferencesDataStore {
|
||||||
legacyKeyName = LEGACY_DEFAULT_KEY_NAME,
|
legacyKeyName = LEGACY_DEFAULT_KEY_NAME,
|
||||||
keyName = PreferencesKeys.BALANCE_HIDING_SETTINGS_KEY.name,
|
keyName = PreferencesKeys.BALANCE_HIDING_SETTINGS_KEY.name,
|
||||||
),
|
),
|
||||||
|
SwapCurrencyIdMigration(),
|
||||||
CleanupKeyMigration(key = APP_LOGS_KEY),
|
CleanupKeyMigration(key = APP_LOGS_KEY),
|
||||||
CleanupKeyMigration(key = IS_WALLET_SWAP_PROMO_OKX_SHOW_KEY),
|
CleanupKeyMigration(key = IS_WALLET_SWAP_PROMO_OKX_SHOW_KEY),
|
||||||
CleanupKeyMigration(key = IS_TOKEN_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 {
|
return runCatching {
|
||||||
Network(
|
Network(
|
||||||
id = Network.ID(value = blockchain.id, derivationPath = derivationPath),
|
id = Network.ID(value = blockchain.toNetworkId(), derivationPath = derivationPath),
|
||||||
backendId = blockchain.toNetworkId(),
|
|
||||||
name = blockchain.fullName,
|
name = blockchain.fullName,
|
||||||
isTestnet = blockchain.isTestnet(),
|
isTestnet = blockchain.isTestnet(),
|
||||||
derivationPath = derivationPath,
|
derivationPath = derivationPath,
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package com.tangem.data.common.network
|
||||||
import com.google.common.truth.Truth
|
import com.google.common.truth.Truth
|
||||||
import com.tangem.blockchain.common.Blockchain
|
import com.tangem.blockchain.common.Blockchain
|
||||||
import com.tangem.blockchainsdk.utils.ExcludedBlockchains
|
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.card.MockScanResponseFactory
|
||||||
import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory
|
import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory
|
||||||
import com.tangem.common.test.domain.wallet.MockUserWalletFactory
|
import com.tangem.common.test.domain.wallet.MockUserWalletFactory
|
||||||
|
|
@ -187,7 +188,7 @@ class NetworkFactoryTest {
|
||||||
userWallet = userWallet,
|
userWallet = userWallet,
|
||||||
expected = MockCryptoCurrencyFactory().ethereum.network.copy(
|
expected = MockCryptoCurrencyFactory().ethereum.network.copy(
|
||||||
id = Network.ID(
|
id = Network.ID(
|
||||||
value = Blockchain.Ethereum.id,
|
value = Blockchain.Ethereum.toNetworkId(),
|
||||||
derivationPath = expectedDerivationPath,
|
derivationPath = expectedDerivationPath,
|
||||||
),
|
),
|
||||||
derivationPath = expectedDerivationPath,
|
derivationPath = expectedDerivationPath,
|
||||||
|
|
@ -201,12 +202,12 @@ class NetworkFactoryTest {
|
||||||
derivationPath: Network.DerivationPath,
|
derivationPath: Network.DerivationPath,
|
||||||
): CreateTestModel.Second {
|
): CreateTestModel.Second {
|
||||||
return 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,
|
derivationPath = derivationPath,
|
||||||
userWallet = userWallet,
|
userWallet = userWallet,
|
||||||
expected = MockCryptoCurrencyFactory().ethereum.network.copy(
|
expected = MockCryptoCurrencyFactory().ethereum.network.copy(
|
||||||
id = Network.ID(
|
id = Network.ID(
|
||||||
value = Blockchain.Ethereum.id,
|
value = Blockchain.Ethereum.toNetworkId(),
|
||||||
derivationPath = derivationPath,
|
derivationPath = derivationPath,
|
||||||
),
|
),
|
||||||
derivationPath = derivationPath,
|
derivationPath = derivationPath,
|
||||||
|
|
@ -227,7 +228,7 @@ class NetworkFactoryTest {
|
||||||
derivationStyleProvider = derivationStyleProvider,
|
derivationStyleProvider = derivationStyleProvider,
|
||||||
canHandleTokens = canHandleTokens,
|
canHandleTokens = canHandleTokens,
|
||||||
expected = MockCryptoCurrencyFactory().ethereum.network.copy(
|
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,
|
derivationPath = expectedDerivationPath,
|
||||||
canHandleTokens = canHandleTokens,
|
canHandleTokens = canHandleTokens,
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package com.tangem.data.networks.converters
|
package com.tangem.data.networks.converters
|
||||||
|
|
||||||
|
import com.tangem.blockchainsdk.utils.toBlockchain
|
||||||
import com.tangem.datasource.local.network.entity.NetworkStatusDM
|
import com.tangem.datasource.local.network.entity.NetworkStatusDM
|
||||||
import com.tangem.domain.models.network.NetworkStatus
|
import com.tangem.domain.models.network.NetworkStatus
|
||||||
import com.tangem.utils.converter.Converter
|
import com.tangem.utils.converter.Converter
|
||||||
|
|
@ -15,17 +16,18 @@ internal object NetworkStatusDataModelConverter : Converter<NetworkStatus, Netwo
|
||||||
return when (val status = value.value) {
|
return when (val status = value.value) {
|
||||||
is NetworkStatus.Verified -> {
|
is NetworkStatus.Verified -> {
|
||||||
val address = NetworkAddressConverter.convertBack(value = status.address)
|
val address = NetworkAddressConverter.convertBack(value = status.address)
|
||||||
|
val blockchainId = value.network.toBlockchain().id
|
||||||
val amountsConverter = NetworkAmountsConverter(
|
val amountsConverter = NetworkAmountsConverter(
|
||||||
rawNetworkId = value.network.rawId,
|
rawNetworkId = blockchainId,
|
||||||
derivationPath = value.network.derivationPath,
|
derivationPath = value.network.derivationPath,
|
||||||
)
|
)
|
||||||
val yieldSupplyStatusConverter = NetworkYieldSupplyStatusConverter(
|
val yieldSupplyStatusConverter = NetworkYieldSupplyStatusConverter(
|
||||||
rawNetworkId = value.network.rawId,
|
rawNetworkId = blockchainId,
|
||||||
derivationPath = value.network.derivationPath,
|
derivationPath = value.network.derivationPath,
|
||||||
)
|
)
|
||||||
|
|
||||||
NetworkStatusDM.Verified(
|
NetworkStatusDM.Verified(
|
||||||
networkId = NetworkStatusDM.ID(value = value.network.rawId),
|
networkId = NetworkStatusDM.ID(value = blockchainId),
|
||||||
derivationPath = NetworkDerivationPathConverter.convertBack(value = value.network.derivationPath),
|
derivationPath = NetworkDerivationPathConverter.convertBack(value = value.network.derivationPath),
|
||||||
selectedAddress = address.selectedAddress,
|
selectedAddress = address.selectedAddress,
|
||||||
availableAddresses = address.addresses,
|
availableAddresses = address.addresses,
|
||||||
|
|
@ -35,9 +37,10 @@ internal object NetworkStatusDataModelConverter : Converter<NetworkStatus, Netwo
|
||||||
}
|
}
|
||||||
is NetworkStatus.NoAccount -> {
|
is NetworkStatus.NoAccount -> {
|
||||||
val address = NetworkAddressConverter.convertBack(value = status.address)
|
val address = NetworkAddressConverter.convertBack(value = status.address)
|
||||||
|
val blockchainId = value.network.toBlockchain().id
|
||||||
|
|
||||||
NetworkStatusDM.NoAccount(
|
NetworkStatusDM.NoAccount(
|
||||||
networkId = NetworkStatusDM.ID(value = value.network.rawId),
|
networkId = NetworkStatusDM.ID(value = blockchainId),
|
||||||
derivationPath = NetworkDerivationPathConverter.convertBack(value = value.network.derivationPath),
|
derivationPath = NetworkDerivationPathConverter.convertBack(value = value.network.derivationPath),
|
||||||
selectedAddress = address.selectedAddress,
|
selectedAddress = address.selectedAddress,
|
||||||
availableAddresses = address.addresses,
|
availableAddresses = address.addresses,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
package com.tangem.data.networks.converters
|
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.data.networks.models.SimpleNetworkStatus
|
||||||
import com.tangem.datasource.local.network.entity.NetworkStatusDM
|
import com.tangem.datasource.local.network.entity.NetworkStatusDM
|
||||||
import com.tangem.domain.models.StatusSource
|
import com.tangem.domain.models.StatusSource
|
||||||
|
|
@ -23,14 +25,15 @@ internal object SimpleNetworkStatusConverter : Converter<NetworkStatusDM, Simple
|
||||||
)
|
)
|
||||||
|
|
||||||
val derivationPath = NetworkDerivationPathConverter.convert(value = value.derivationPath)
|
val derivationPath = NetworkDerivationPathConverter.convert(value = value.derivationPath)
|
||||||
|
val rawNetworkId = value.networkId.value
|
||||||
|
|
||||||
val amountsConverter = NetworkAmountsConverter(
|
val amountsConverter = NetworkAmountsConverter(
|
||||||
rawNetworkId = value.networkId.value,
|
rawNetworkId = rawNetworkId,
|
||||||
derivationPath = derivationPath,
|
derivationPath = derivationPath,
|
||||||
)
|
)
|
||||||
|
|
||||||
val yieldSupplyStatusConverter = NetworkYieldSupplyStatusConverter(
|
val yieldSupplyStatusConverter = NetworkYieldSupplyStatusConverter(
|
||||||
rawNetworkId = value.networkId.value,
|
rawNetworkId = rawNetworkId,
|
||||||
derivationPath = derivationPath,
|
derivationPath = derivationPath,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -54,9 +57,11 @@ internal object SimpleNetworkStatusConverter : Converter<NetworkStatusDM, Simple
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val rawId = Blockchain.fromId(rawNetworkId).toNetworkId()
|
||||||
|
|
||||||
return SimpleNetworkStatus(
|
return SimpleNetworkStatus(
|
||||||
id = Network.ID(
|
id = Network.ID(
|
||||||
value = value.networkId.value,
|
value = rawId,
|
||||||
derivationPath = NetworkDerivationPathConverter.convert(value = value.derivationPath),
|
derivationPath = NetworkDerivationPathConverter.convert(value = value.derivationPath),
|
||||||
),
|
),
|
||||||
value = status,
|
value = status,
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package com.tangem.data.networks.store
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.datastore.core.DataStore
|
import androidx.datastore.core.DataStore
|
||||||
|
import com.tangem.blockchainsdk.utils.toBlockchain
|
||||||
import com.tangem.data.networks.converters.NetworkStatusDataModelConverter
|
import com.tangem.data.networks.converters.NetworkStatusDataModelConverter
|
||||||
import com.tangem.data.networks.converters.SimpleNetworkStatusConverter
|
import com.tangem.data.networks.converters.SimpleNetworkStatusConverter
|
||||||
import com.tangem.data.networks.models.SimpleNetworkStatus
|
import com.tangem.data.networks.models.SimpleNetworkStatus
|
||||||
|
|
@ -27,15 +28,15 @@ internal typealias WalletIdWithStatusDM = Map<String, Set<NetworkStatusDM>>
|
||||||
* Default implementation of [NetworksStatusesStore]
|
* Default implementation of [NetworksStatusesStore]
|
||||||
*
|
*
|
||||||
* @param context context
|
* @param context context
|
||||||
|
* @param scope app coroutine scope
|
||||||
* @property runtimeStore runtime store
|
* @property runtimeStore runtime store
|
||||||
* @property persistenceDataStore persistence store
|
* @property persistenceDataStore persistence store
|
||||||
* @param dispatchers dispatchers
|
|
||||||
*/
|
*/
|
||||||
internal class DefaultNetworksStatusesStore(
|
internal class DefaultNetworksStatusesStore(
|
||||||
context: Context,
|
context: Context,
|
||||||
|
scope: AppCoroutineScope,
|
||||||
private val runtimeStore: RuntimeSharedStore<WalletIdWithSimpleStatus>,
|
private val runtimeStore: RuntimeSharedStore<WalletIdWithSimpleStatus>,
|
||||||
private val persistenceDataStore: DataStore<WalletIdWithStatusDM>,
|
private val persistenceDataStore: DataStore<WalletIdWithStatusDM>,
|
||||||
private val scope: AppCoroutineScope,
|
|
||||||
) : NetworksStatusesStore {
|
) : NetworksStatusesStore {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
|
@ -112,7 +113,8 @@ internal class DefaultNetworksStatusesStore(
|
||||||
storedStatuses.toMutableMap().apply {
|
storedStatuses.toMutableMap().apply {
|
||||||
val updatedValues = this[userWalletId.stringValue].orEmpty().filterNot {
|
val updatedValues = this[userWalletId.stringValue].orEmpty().filterNot {
|
||||||
networks.any { network ->
|
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
|
package com.tangem.data.networks.converters
|
||||||
|
|
||||||
import com.google.common.truth.Truth
|
import com.google.common.truth.Truth
|
||||||
|
import com.tangem.blockchainsdk.utils.toBlockchain
|
||||||
import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory
|
import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory
|
||||||
import com.tangem.datasource.local.network.entity.NetworkStatusDM
|
import com.tangem.datasource.local.network.entity.NetworkStatusDM
|
||||||
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(
|
expected = Verified(
|
||||||
networkId = ID(network.rawId),
|
networkId = ID(network.toBlockchain().id),
|
||||||
derivationPath = DerivationPath(
|
derivationPath = DerivationPath(
|
||||||
value = "",
|
value = "",
|
||||||
type = DerivationPath.Type.NONE,
|
type = DerivationPath.Type.NONE,
|
||||||
|
|
@ -119,7 +120,7 @@ internal class NetworkStatusDataModelConverterTest {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
expected = NoAccount(
|
expected = NoAccount(
|
||||||
networkId = ID(network.rawId),
|
networkId = ID(network.toBlockchain().id),
|
||||||
derivationPath = DerivationPath(
|
derivationPath = DerivationPath(
|
||||||
value = "",
|
value = "",
|
||||||
type = DerivationPath.Type.NONE,
|
type = DerivationPath.Type.NONE,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package com.tangem.data.networks.converters
|
package com.tangem.data.networks.converters
|
||||||
|
|
||||||
import com.google.common.truth.Truth
|
import com.google.common.truth.Truth
|
||||||
|
import com.tangem.blockchainsdk.utils.toBlockchain
|
||||||
import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory
|
import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory
|
||||||
import com.tangem.data.networks.models.SimpleNetworkStatus
|
import com.tangem.data.networks.models.SimpleNetworkStatus
|
||||||
import com.tangem.datasource.local.network.entity.NetworkStatusDM
|
import com.tangem.datasource.local.network.entity.NetworkStatusDM
|
||||||
|
|
@ -48,7 +49,7 @@ internal class SimpleNetworkStatusConverterTest {
|
||||||
// region Verified
|
// region Verified
|
||||||
ConvertModel(
|
ConvertModel(
|
||||||
value = Verified(
|
value = Verified(
|
||||||
networkId = ID(network.rawId),
|
networkId = ID(network.toBlockchain().id),
|
||||||
derivationPath = DerivationPath(
|
derivationPath = DerivationPath(
|
||||||
value = "card",
|
value = "card",
|
||||||
type = DerivationPath.Type.CARD,
|
type = DerivationPath.Type.CARD,
|
||||||
|
|
@ -74,7 +75,7 @@ internal class SimpleNetworkStatusConverterTest {
|
||||||
),
|
),
|
||||||
expected = SimpleNetworkStatus(
|
expected = SimpleNetworkStatus(
|
||||||
id = Network.ID(
|
id = Network.ID(
|
||||||
value = network.rawId,
|
value = network.backendId,
|
||||||
derivationPath = Network.DerivationPath.Card("card"),
|
derivationPath = Network.DerivationPath.Card("card"),
|
||||||
),
|
),
|
||||||
value = NetworkStatus.Verified(
|
value = NetworkStatus.Verified(
|
||||||
|
|
@ -116,7 +117,7 @@ internal class SimpleNetworkStatusConverterTest {
|
||||||
// region NoAccount
|
// region NoAccount
|
||||||
ConvertModel(
|
ConvertModel(
|
||||||
value = NoAccount(
|
value = NoAccount(
|
||||||
networkId = ID(network.rawId),
|
networkId = ID(network.toBlockchain().id),
|
||||||
derivationPath = DerivationPath(
|
derivationPath = DerivationPath(
|
||||||
value = "card",
|
value = "card",
|
||||||
type = DerivationPath.Type.CARD,
|
type = DerivationPath.Type.CARD,
|
||||||
|
|
@ -137,7 +138,7 @@ internal class SimpleNetworkStatusConverterTest {
|
||||||
),
|
),
|
||||||
expected = SimpleNetworkStatus(
|
expected = SimpleNetworkStatus(
|
||||||
id = Network.ID(
|
id = Network.ID(
|
||||||
value = network.rawId,
|
value = network.backendId,
|
||||||
derivationPath = Network.DerivationPath.Card("card"),
|
derivationPath = Network.DerivationPath.Card("card"),
|
||||||
),
|
),
|
||||||
value = NetworkStatus.NoAccount(
|
value = NetworkStatus.NoAccount(
|
||||||
|
|
@ -168,7 +169,7 @@ internal class SimpleNetworkStatusConverterTest {
|
||||||
// region Error
|
// region Error
|
||||||
ConvertModel(
|
ConvertModel(
|
||||||
value = Verified(
|
value = Verified(
|
||||||
networkId = ID(network.rawId),
|
networkId = ID(network.toBlockchain().id),
|
||||||
derivationPath = DerivationPath(
|
derivationPath = DerivationPath(
|
||||||
value = "card",
|
value = "card",
|
||||||
type = DerivationPath.Type.CARD,
|
type = DerivationPath.Type.CARD,
|
||||||
|
|
@ -189,7 +190,7 @@ internal class SimpleNetworkStatusConverterTest {
|
||||||
),
|
),
|
||||||
ConvertModel(
|
ConvertModel(
|
||||||
value = Verified(
|
value = Verified(
|
||||||
networkId = ID(network.rawId),
|
networkId = ID(network.toBlockchain().id),
|
||||||
derivationPath = DerivationPath(
|
derivationPath = DerivationPath(
|
||||||
value = "card",
|
value = "card",
|
||||||
type = DerivationPath.Type.CARD,
|
type = DerivationPath.Type.CARD,
|
||||||
|
|
@ -205,7 +206,7 @@ internal class SimpleNetworkStatusConverterTest {
|
||||||
),
|
),
|
||||||
ConvertModel(
|
ConvertModel(
|
||||||
value = Verified(
|
value = Verified(
|
||||||
networkId = ID(network.rawId),
|
networkId = ID(network.toBlockchain().id),
|
||||||
derivationPath = DerivationPath(
|
derivationPath = DerivationPath(
|
||||||
value = "card",
|
value = "card",
|
||||||
type = DerivationPath.Type.CARD,
|
type = DerivationPath.Type.CARD,
|
||||||
|
|
@ -230,7 +231,7 @@ internal class SimpleNetworkStatusConverterTest {
|
||||||
),
|
),
|
||||||
ConvertModel(
|
ConvertModel(
|
||||||
value = NoAccount(
|
value = NoAccount(
|
||||||
networkId = ID(network.rawId),
|
networkId = ID(network.toBlockchain().id),
|
||||||
derivationPath = DerivationPath(
|
derivationPath = DerivationPath(
|
||||||
value = "card",
|
value = "card",
|
||||||
type = DerivationPath.Type.CARD,
|
type = DerivationPath.Type.CARD,
|
||||||
|
|
@ -255,7 +256,7 @@ internal class SimpleNetworkStatusConverterTest {
|
||||||
),
|
),
|
||||||
ConvertModel(
|
ConvertModel(
|
||||||
value = NoAccount(
|
value = NoAccount(
|
||||||
networkId = ID(network.rawId),
|
networkId = ID(network.toBlockchain().id),
|
||||||
derivationPath = DerivationPath(
|
derivationPath = DerivationPath(
|
||||||
value = "card",
|
value = "card",
|
||||||
type = DerivationPath.Type.CARD,
|
type = DerivationPath.Type.CARD,
|
||||||
|
|
@ -276,7 +277,7 @@ internal class SimpleNetworkStatusConverterTest {
|
||||||
),
|
),
|
||||||
ConvertModel(
|
ConvertModel(
|
||||||
value = NoAccount(
|
value = NoAccount(
|
||||||
networkId = ID(network.rawId),
|
networkId = ID(network.toBlockchain().id),
|
||||||
derivationPath = DerivationPath(
|
derivationPath = DerivationPath(
|
||||||
value = "card",
|
value = "card",
|
||||||
type = DerivationPath.Type.CARD,
|
type = DerivationPath.Type.CARD,
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ internal class CommonNetworkStatusFetcherTest {
|
||||||
val userWalletId = UserWalletId("011")
|
val userWalletId = UserWalletId("011")
|
||||||
val network = cryptoCurrencyFactory.ethereum.network
|
val network = cryptoCurrencyFactory.ethereum.network
|
||||||
val extraTokens = setOf(
|
val extraTokens = setOf(
|
||||||
cryptoCurrencyFactory.createToken(Blockchain.Ethereum) as CryptoCurrency.Token,
|
cryptoCurrencyFactory.createToken(Blockchain.Ethereum),
|
||||||
)
|
)
|
||||||
val updateException = IllegalStateException()
|
val updateException = IllegalStateException()
|
||||||
|
|
||||||
|
|
@ -80,7 +80,7 @@ internal class CommonNetworkStatusFetcherTest {
|
||||||
val userWalletId = UserWalletId("011")
|
val userWalletId = UserWalletId("011")
|
||||||
val network = cryptoCurrencyFactory.ethereum.network
|
val network = cryptoCurrencyFactory.ethereum.network
|
||||||
val extraTokens = setOf(
|
val extraTokens = setOf(
|
||||||
cryptoCurrencyFactory.createToken(Blockchain.Ethereum) as CryptoCurrency.Token,
|
cryptoCurrencyFactory.createToken(Blockchain.Ethereum),
|
||||||
)
|
)
|
||||||
val updateResult = model.updateResult
|
val updateResult = model.updateResult
|
||||||
val status = model.status
|
val status = model.status
|
||||||
|
|
@ -143,15 +143,15 @@ internal class CommonNetworkStatusFetcherTest {
|
||||||
it.copy(
|
it.copy(
|
||||||
amounts = mapOf(
|
amounts = mapOf(
|
||||||
CryptoCurrency.ID.fromValue(
|
CryptoCurrency.ID.fromValue(
|
||||||
value = "token⟨ETH⟩NEVER-MIND⚓NEVER-MIND",
|
value = "token⟨ethereum⟩NEVER-MIND⚓NEVER-MIND",
|
||||||
) to NetworkStatus.Amount.NotFound,
|
) to NetworkStatus.Amount.NotFound,
|
||||||
),
|
),
|
||||||
pendingTransactions = mapOf(
|
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(
|
yieldSupplyStatuses = mapOf(
|
||||||
CryptoCurrency.ID.fromValue(
|
CryptoCurrency.ID.fromValue(
|
||||||
value = "token⟨ETH⟩NEVER-MIND⚓NEVER-MIND",
|
value = "token⟨ethereum⟩NEVER-MIND⚓NEVER-MIND",
|
||||||
) to null,
|
) to null,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -176,7 +176,7 @@ internal class Bip321PaymentUriParserTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `includes tokens on matching network`() {
|
fun `includes tokens on matching network`() {
|
||||||
val btcToken = buildToken("BTC", "RUNE", "contractAddr")
|
val btcToken = buildToken("bitcoin", "RUNE", "contractAddr")
|
||||||
|
|
||||||
val result = parser.parse(
|
val result = parser.parse(
|
||||||
qrCode = "bitcoin:1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa?amount=0.01",
|
qrCode = "bitcoin:1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa?amount=0.01",
|
||||||
|
|
@ -263,7 +263,13 @@ internal class Bip321PaymentUriParserTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `memo on network with memo support is not unsupported`() {
|
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(
|
val result = parser.parse(
|
||||||
qrCode = "ripple:rAddress?dt=12345",
|
qrCode = "ripple:rAddress?dt=12345",
|
||||||
|
|
@ -299,9 +305,9 @@ internal class Bip321PaymentUriParserTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val bitcoinCoin = buildCoin("BTC", "Bitcoin", "BTC", decimals = 8)
|
private val bitcoinCoin = buildCoin("bitcoin", "Bitcoin", "BTC", decimals = 8)
|
||||||
private val litecoinCoin = buildCoin("LTC", "Litecoin", "LTC", decimals = 8)
|
private val litecoinCoin = buildCoin("litecoin", "Litecoin", "LTC", decimals = 8)
|
||||||
private val dogecoinCoin = buildCoin("DOGE", "Dogecoin", "DOGE", decimals = 8)
|
private val dogecoinCoin = buildCoin("dogecoin", "Dogecoin", "DOGE", decimals = 8)
|
||||||
|
|
||||||
private fun buildCoin(
|
private fun buildCoin(
|
||||||
rawNetworkId: String,
|
rawNetworkId: String,
|
||||||
|
|
@ -349,8 +355,7 @@ internal class Bip321PaymentUriParserTest {
|
||||||
extrasType: Network.TransactionExtrasType = Network.TransactionExtrasType.NONE,
|
extrasType: Network.TransactionExtrasType = Network.TransactionExtrasType.NONE,
|
||||||
): Network {
|
): Network {
|
||||||
return Network(
|
return Network(
|
||||||
id = Network.ID(Network.RawID(rawNetworkId), Network.DerivationPath.None),
|
id = Network.ID(value = rawNetworkId, derivationPath = Network.DerivationPath.None),
|
||||||
backendId = rawNetworkId,
|
|
||||||
name = name,
|
name = name,
|
||||||
currencySymbol = symbol,
|
currencySymbol = symbol,
|
||||||
derivationPath = Network.DerivationPath.None,
|
derivationPath = Network.DerivationPath.None,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
package com.tangem.data.qrscanning
|
package com.tangem.data.qrscanning
|
||||||
|
|
||||||
import com.google.common.truth.Truth
|
import com.google.common.truth.Truth
|
||||||
import com.tangem.blockchain.common.Blockchain
|
|
||||||
import com.tangem.data.qrscanning.parser.QrContentClassifierParser
|
import com.tangem.data.qrscanning.parser.QrContentClassifierParser
|
||||||
import com.tangem.data.qrscanning.repository.DefaultQrScanningEventsRepository
|
import com.tangem.data.qrscanning.repository.DefaultQrScanningEventsRepository
|
||||||
import com.tangem.domain.models.currency.CryptoCurrency
|
import com.tangem.domain.models.currency.CryptoCurrency
|
||||||
|
|
@ -78,7 +77,8 @@ internal class DefaultQrScanningEventsRepositoryTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testBip021() {
|
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(
|
positiveCase(
|
||||||
"$schema1:$address1",
|
"$schema1:$address1",
|
||||||
QrResult(address = address1),
|
QrResult(address = address1),
|
||||||
|
|
@ -128,7 +128,8 @@ internal class DefaultQrScanningEventsRepositoryTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testErc681Coin() {
|
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(
|
positiveCase(
|
||||||
address2,
|
address2,
|
||||||
QrResult(address = address2),
|
QrResult(address = address2),
|
||||||
|
|
@ -183,7 +184,8 @@ internal class DefaultQrScanningEventsRepositoryTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testErc681Token() {
|
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(
|
positiveCase(
|
||||||
address2,
|
address2,
|
||||||
QrResult(address = address2),
|
QrResult(address = address2),
|
||||||
|
|
|
||||||
|
|
@ -382,8 +382,7 @@ internal class Eip681PaymentUriParserTest {
|
||||||
|
|
||||||
private fun buildNetwork(rawNetworkId: String): Network {
|
private fun buildNetwork(rawNetworkId: String): Network {
|
||||||
return Network(
|
return Network(
|
||||||
id = Network.ID(Network.RawID(rawNetworkId), Network.DerivationPath.None),
|
id = Network.ID(value = rawNetworkId, derivationPath = Network.DerivationPath.None),
|
||||||
backendId = rawNetworkId,
|
|
||||||
name = rawNetworkId,
|
name = rawNetworkId,
|
||||||
currencySymbol = rawNetworkId.take(3).uppercase(),
|
currencySymbol = rawNetworkId.take(3).uppercase(),
|
||||||
derivationPath = Network.DerivationPath.None,
|
derivationPath = Network.DerivationPath.None,
|
||||||
|
|
|
||||||
|
|
@ -233,8 +233,7 @@ internal class QrContentClassifierTest {
|
||||||
|
|
||||||
private fun buildNetwork(rawNetworkId: String): Network {
|
private fun buildNetwork(rawNetworkId: String): Network {
|
||||||
return Network(
|
return Network(
|
||||||
id = Network.ID(Network.RawID(rawNetworkId), Network.DerivationPath.None),
|
id = Network.ID(value = rawNetworkId, derivationPath = Network.DerivationPath.None),
|
||||||
backendId = rawNetworkId,
|
|
||||||
name = rawNetworkId,
|
name = rawNetworkId,
|
||||||
currencySymbol = rawNetworkId.take(3).uppercase(),
|
currencySymbol = rawNetworkId.take(3).uppercase(),
|
||||||
derivationPath = Network.DerivationPath.None,
|
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(
|
private val solanaCoin = CryptoCurrency.Coin(
|
||||||
id = CryptoCurrency.ID(
|
id = CryptoCurrency.ID(
|
||||||
prefix = CryptoCurrency.ID.Prefix.COIN_PREFIX,
|
prefix = CryptoCurrency.ID.Prefix.COIN_PREFIX,
|
||||||
body = CryptoCurrency.ID.Body.NetworkId("SOLANA"),
|
body = CryptoCurrency.ID.Body.NetworkId("solana"),
|
||||||
suffix = CryptoCurrency.ID.Suffix.RawID("SOLANA"),
|
suffix = CryptoCurrency.ID.Suffix.RawID("solana"),
|
||||||
),
|
),
|
||||||
network = solanaNetwork,
|
network = solanaNetwork,
|
||||||
name = "Solana",
|
name = "Solana",
|
||||||
|
|
@ -217,7 +217,7 @@ internal class SolanaPaymentUriParserTest {
|
||||||
private val usdcToken = CryptoCurrency.Token(
|
private val usdcToken = CryptoCurrency.Token(
|
||||||
id = CryptoCurrency.ID(
|
id = CryptoCurrency.ID(
|
||||||
prefix = CryptoCurrency.ID.Prefix.TOKEN_PREFIX,
|
prefix = CryptoCurrency.ID.Prefix.TOKEN_PREFIX,
|
||||||
body = CryptoCurrency.ID.Body.NetworkId("SOLANA"),
|
body = CryptoCurrency.ID.Body.NetworkId("solana"),
|
||||||
suffix = CryptoCurrency.ID.Suffix.RawID("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"),
|
suffix = CryptoCurrency.ID.Suffix.RawID("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"),
|
||||||
),
|
),
|
||||||
network = solanaNetwork,
|
network = solanaNetwork,
|
||||||
|
|
@ -231,8 +231,7 @@ internal class SolanaPaymentUriParserTest {
|
||||||
|
|
||||||
private fun buildNetwork(rawNetworkId: String, name: String, symbol: String): Network {
|
private fun buildNetwork(rawNetworkId: String, name: String, symbol: String): Network {
|
||||||
return Network(
|
return Network(
|
||||||
id = Network.ID(Network.RawID(rawNetworkId), Network.DerivationPath.None),
|
id = Network.ID(value = rawNetworkId, derivationPath = Network.DerivationPath.None),
|
||||||
backendId = rawNetworkId,
|
|
||||||
name = name,
|
name = name,
|
||||||
currencySymbol = symbol,
|
currencySymbol = symbol,
|
||||||
derivationPath = Network.DerivationPath.None,
|
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(
|
private val tronCoin = CryptoCurrency.Coin(
|
||||||
id = CryptoCurrency.ID(
|
id = CryptoCurrency.ID(
|
||||||
prefix = CryptoCurrency.ID.Prefix.COIN_PREFIX,
|
prefix = CryptoCurrency.ID.Prefix.COIN_PREFIX,
|
||||||
body = CryptoCurrency.ID.Body.NetworkId("TRON"),
|
body = CryptoCurrency.ID.Body.NetworkId("tron"),
|
||||||
suffix = CryptoCurrency.ID.Suffix.RawID("TRON"),
|
suffix = CryptoCurrency.ID.Suffix.RawID("tron"),
|
||||||
),
|
),
|
||||||
network = tronNetwork,
|
network = tronNetwork,
|
||||||
name = "Tron",
|
name = "Tron",
|
||||||
|
|
@ -257,7 +257,7 @@ internal class TronPaymentUriParserTest {
|
||||||
private val usdtToken = CryptoCurrency.Token(
|
private val usdtToken = CryptoCurrency.Token(
|
||||||
id = CryptoCurrency.ID(
|
id = CryptoCurrency.ID(
|
||||||
prefix = CryptoCurrency.ID.Prefix.TOKEN_PREFIX,
|
prefix = CryptoCurrency.ID.Prefix.TOKEN_PREFIX,
|
||||||
body = CryptoCurrency.ID.Body.NetworkId("TRON"),
|
body = CryptoCurrency.ID.Body.NetworkId("tron"),
|
||||||
suffix = CryptoCurrency.ID.Suffix.RawID("TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t"),
|
suffix = CryptoCurrency.ID.Suffix.RawID("TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t"),
|
||||||
),
|
),
|
||||||
network = tronNetwork,
|
network = tronNetwork,
|
||||||
|
|
@ -271,8 +271,7 @@ internal class TronPaymentUriParserTest {
|
||||||
|
|
||||||
private fun buildNetwork(rawNetworkId: String, name: String, symbol: String): Network {
|
private fun buildNetwork(rawNetworkId: String, name: String, symbol: String): Network {
|
||||||
return Network(
|
return Network(
|
||||||
id = Network.ID(Network.RawID(rawNetworkId), Network.DerivationPath.None),
|
id = Network.ID(value = rawNetworkId, derivationPath = Network.DerivationPath.None),
|
||||||
backendId = rawNetworkId,
|
|
||||||
name = name,
|
name = name,
|
||||||
currencySymbol = symbol,
|
currencySymbol = symbol,
|
||||||
derivationPath = Network.DerivationPath.None,
|
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.ethereum.eip1559.isGaslessTxSupported
|
||||||
import com.tangem.blockchain.blockchains.polkadot.ExistentialDepositProvider
|
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.common.getTotalStakingBalance
|
||||||
import com.tangem.data.tokens.converters.UtxoConverter
|
import com.tangem.data.tokens.converters.UtxoConverter
|
||||||
import com.tangem.domain.models.currency.CryptoCurrency
|
import com.tangem.domain.models.currency.CryptoCurrency
|
||||||
|
|
@ -67,7 +71,7 @@ internal class DefaultCurrencyChecksRepository(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isNetworkSupportedForGaslessTx(network: Network): Boolean {
|
override fun isNetworkSupportedForGaslessTx(network: Network): Boolean {
|
||||||
val blockchain = Blockchain.fromId(network.rawId)
|
val blockchain = network.toBlockchain()
|
||||||
return blockchain.isGaslessTxSupported
|
return blockchain.isGaslessTxSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package com.tangem.data.transaction
|
package com.tangem.data.transaction
|
||||||
|
|
||||||
import com.tangem.blockchain.common.Blockchain
|
|
||||||
import com.tangem.blockchain.common.Token
|
import com.tangem.blockchain.common.Token
|
||||||
|
import com.tangem.blockchainsdk.utils.toBlockchain
|
||||||
import com.tangem.data.common.currency.ResponseCryptoCurrenciesFactory
|
import com.tangem.data.common.currency.ResponseCryptoCurrenciesFactory
|
||||||
import com.tangem.data.transaction.convertes.GaslessSignedTransactionResultConverter
|
import com.tangem.data.transaction.convertes.GaslessSignedTransactionResultConverter
|
||||||
import com.tangem.data.transaction.convertes.GaslessTransactionRequestBuilder
|
import com.tangem.data.transaction.convertes.GaslessTransactionRequestBuilder
|
||||||
|
|
@ -45,7 +45,7 @@ class DefaultGaslessTransactionRepository(
|
||||||
|
|
||||||
val supportedTokensData = gaslessTxServiceApi.getSupportedTokens().getOrThrow()
|
val supportedTokensData = gaslessTxServiceApi.getSupportedTokens().getOrThrow()
|
||||||
if (supportedTokensData.isSuccess) {
|
if (supportedTokensData.isSuccess) {
|
||||||
val networkBlockchain = Blockchain.fromId(network.rawId)
|
val networkBlockchain = network.toBlockchain()
|
||||||
val supportedTokens = supportedTokensData.result.tokens
|
val supportedTokens = supportedTokensData.result.tokens
|
||||||
.filter {
|
.filter {
|
||||||
it.chainId == networkBlockchain.getChainId()
|
it.chainId == networkBlockchain.getChainId()
|
||||||
|
|
@ -100,7 +100,7 @@ class DefaultGaslessTransactionRepository(
|
||||||
network: Network,
|
network: Network,
|
||||||
eip7702Auth: Eip7702Authorization?,
|
eip7702Auth: Eip7702Authorization?,
|
||||||
): GaslessSignedTransactionResult = withContext(coroutineDispatcherProvider.io) {
|
): GaslessSignedTransactionResult = withContext(coroutineDispatcherProvider.io) {
|
||||||
val blockchain = Blockchain.fromId(network.rawId)
|
val blockchain = network.toBlockchain()
|
||||||
val transactionRequest = gaslessTransactionRequestBuilder.build(
|
val transactionRequest = gaslessTransactionRequestBuilder.build(
|
||||||
gaslessTransaction = gaslessTransactionData,
|
gaslessTransaction = gaslessTransactionData,
|
||||||
signature = signature,
|
signature = signature,
|
||||||
|
|
@ -124,7 +124,7 @@ class DefaultGaslessTransactionRepository(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getChainIdForNetwork(network: Network): Int {
|
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}")
|
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.Blockchain
|
||||||
import com.tangem.blockchain.common.Token
|
import com.tangem.blockchain.common.Token
|
||||||
|
import com.tangem.blockchainsdk.utils.toBlockchain
|
||||||
import com.tangem.data.common.currency.ResponseCryptoCurrenciesFactory
|
import com.tangem.data.common.currency.ResponseCryptoCurrenciesFactory
|
||||||
import com.tangem.domain.models.currency.CryptoCurrency
|
import com.tangem.domain.models.currency.CryptoCurrency
|
||||||
import com.tangem.domain.models.network.Network
|
import com.tangem.domain.models.network.Network
|
||||||
|
|
@ -30,7 +31,7 @@ class MockedGaslessTransactionRepository(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getChainIdForNetwork(network: Network): Int {
|
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}")
|
return networkBlockchain.getChainId() ?: error("ChainId not found for blockchain ${networkBlockchain.name}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -171,7 +171,11 @@ class DefaultAllowanceRepositoryTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `returns NotEnough when partial allowance for non-tether token`() = runTest {
|
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 {
|
coEvery {
|
||||||
(approverWalletManager as Approver).getAllowance(spenderAddress, any())
|
(approverWalletManager as Approver).getAllowance(spenderAddress, any())
|
||||||
|
|
@ -187,7 +191,7 @@ class DefaultAllowanceRepositoryTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `returns NotEnough when partial allowance for tether on non-ethereum network`() = runTest {
|
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 {
|
coEvery {
|
||||||
(approverWalletManager as Approver).getAllowance(spenderAddress, any())
|
(approverWalletManager as Approver).getAllowance(spenderAddress, any())
|
||||||
|
|
@ -200,7 +204,7 @@ class DefaultAllowanceRepositoryTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `returns ResetNeeded when partial allowance for tether on ethereum`() = runTest {
|
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 {
|
coEvery {
|
||||||
(approverWalletManager as Approver).getAllowance(spenderAddress, any())
|
(approverWalletManager as Approver).getAllowance(spenderAddress, any())
|
||||||
|
|
@ -216,7 +220,7 @@ class DefaultAllowanceRepositoryTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `returns ResetNeeded when partial allowance for tether on ethereum testnet`() = runTest {
|
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 {
|
coEvery {
|
||||||
(approverWalletManager as Approver).getAllowance(spenderAddress, any())
|
(approverWalletManager as Approver).getAllowance(spenderAddress, any())
|
||||||
|
|
@ -248,8 +252,7 @@ class DefaultAllowanceRepositoryTest {
|
||||||
private fun buildNetwork(rawNetworkId: String): Network {
|
private fun buildNetwork(rawNetworkId: String): Network {
|
||||||
val derivationPath = Network.DerivationPath.None
|
val derivationPath = Network.DerivationPath.None
|
||||||
return Network(
|
return Network(
|
||||||
id = Network.ID(Network.RawID(rawNetworkId), derivationPath),
|
id = Network.ID(value = rawNetworkId, derivationPath = derivationPath),
|
||||||
backendId = rawNetworkId,
|
|
||||||
name = rawNetworkId.replaceFirstChar { it.uppercase() },
|
name = rawNetworkId.replaceFirstChar { it.uppercase() },
|
||||||
currencySymbol = "ETH",
|
currencySymbol = "ETH",
|
||||||
derivationPath = derivationPath,
|
derivationPath = derivationPath,
|
||||||
|
|
@ -263,7 +266,7 @@ class DefaultAllowanceRepositoryTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildToken(
|
private fun buildToken(
|
||||||
rawNetworkId: String = "ETH",
|
rawNetworkId: String = "ethereum",
|
||||||
rawCurrencyId: String = "tether",
|
rawCurrencyId: String = "tether",
|
||||||
contractAddress: String = "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
contractAddress: String = "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
||||||
): CryptoCurrency.Token {
|
): CryptoCurrency.Token {
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import com.reown.walletkit.client.Wallet
|
||||||
import com.tangem.blockchain.common.Blockchain
|
import com.tangem.blockchain.common.Blockchain
|
||||||
import com.tangem.blockchain.common.address.AddressType
|
import com.tangem.blockchain.common.address.AddressType
|
||||||
import com.tangem.blockchainsdk.utils.toBlockchain
|
import com.tangem.blockchainsdk.utils.toBlockchain
|
||||||
|
import com.tangem.blockchainsdk.utils.toNetworkId
|
||||||
import com.tangem.data.common.currency.isCustomCoin
|
import com.tangem.data.common.currency.isCustomCoin
|
||||||
import com.tangem.data.walletconnect.model.CAIP10
|
import com.tangem.data.walletconnect.model.CAIP10
|
||||||
import com.tangem.domain.account.status.producer.SingleAccountStatusListProducer
|
import com.tangem.domain.account.status.producer.SingleAccountStatusListProducer
|
||||||
|
|
@ -84,7 +85,7 @@ internal class WcNetworksConverter @Inject constructor(
|
||||||
val blockchain = namespaceConverters
|
val blockchain = namespaceConverters
|
||||||
.firstNotNullOfOrNull { it.toBlockchain(rawChainId) } ?: return listOf()
|
.firstNotNullOfOrNull { it.toBlockchain(rawChainId) } ?: return listOf()
|
||||||
|
|
||||||
val allCoinNetwork = portfolioNetworks.filter { it.rawId == blockchain.id }
|
val allCoinNetwork = portfolioNetworks.filter { it.rawId == blockchain.toNetworkId() }
|
||||||
return allCoinNetwork
|
return allCoinNetwork
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -103,7 +104,7 @@ internal class WcNetworksConverter @Inject constructor(
|
||||||
?: return@mapNotNullTo null
|
?: return@mapNotNullTo null
|
||||||
portfolioNetworks
|
portfolioNetworks
|
||||||
// find all derivation
|
// find all derivation
|
||||||
.filter { it.rawId == blockchain.id }
|
.filter { it.rawId == blockchain.toNetworkId() }
|
||||||
// find equal address
|
// find equal address
|
||||||
.firstOrNull { network ->
|
.firstOrNull { network ->
|
||||||
val walletAddress = getAddressForWC(wallet.walletId, 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)
|
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||||
class DefaultYieldSupplyTransactionRepositoryTest {
|
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 mockedContractAddress = "0x000000000000000000000000000000000000"
|
||||||
private val yieldContractAddress = "0x1234"
|
private val yieldContractAddress = "0x1234"
|
||||||
|
|
||||||
private val userWalletId = mockk<UserWalletId>()
|
private val userWalletId = mockk<UserWalletId>()
|
||||||
private val cryptoCurrency = mockk<CryptoCurrency.Token>(relaxed = true) {
|
private val cryptoCurrency = mockk<CryptoCurrency.Token>(relaxed = true) {
|
||||||
every { network.id } returns networkId
|
every { network.id } returns networkId
|
||||||
|
every { network.backendId } returns networkId.rawId.value
|
||||||
every { contractAddress } returns mockedContractAddress
|
every { contractAddress } returns mockedContractAddress
|
||||||
}
|
}
|
||||||
private val cryptoCurrencyStatus = mockk<CryptoCurrencyStatus>(relaxed = true) {
|
private val cryptoCurrencyStatus = mockk<CryptoCurrencyStatus>(relaxed = true) {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package com.tangem.domain.account.status.utils
|
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.AccountList
|
||||||
import com.tangem.domain.account.models.AccountStatusList
|
import com.tangem.domain.account.models.AccountStatusList
|
||||||
import com.tangem.domain.account.status.model.AccountCryptoCurrency
|
import com.tangem.domain.account.status.model.AccountCryptoCurrency
|
||||||
|
|
@ -180,7 +180,7 @@ internal object AccountCryptoCurrencyStatusFinder {
|
||||||
contractAddress: String?,
|
contractAddress: String?,
|
||||||
): AccountCryptoCurrency? {
|
): AccountCryptoCurrency? {
|
||||||
return accountList.getExpectedAccounts(
|
return accountList.getExpectedAccounts(
|
||||||
rawNetworkId = networkId.rawId.value,
|
rawNetworkId = networkId.rawId,
|
||||||
derivationPath = derivationPath,
|
derivationPath = derivationPath,
|
||||||
)
|
)
|
||||||
.asSequence()
|
.asSequence()
|
||||||
|
|
@ -220,7 +220,7 @@ internal object AccountCryptoCurrencyStatusFinder {
|
||||||
|
|
||||||
internal fun AccountStatusList.getExpectedAccountStatuses(networkId: Network.ID): List<AccountStatus> {
|
internal fun AccountStatusList.getExpectedAccountStatuses(networkId: Network.ID): List<AccountStatus> {
|
||||||
val possibleAccountIndex = getAccountIndexOrNull(
|
val possibleAccountIndex = getAccountIndexOrNull(
|
||||||
rawNetworkId = networkId.rawId.value,
|
rawNetworkId = networkId.rawId,
|
||||||
derivationPath = networkId.derivationPath,
|
derivationPath = networkId.derivationPath,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -239,7 +239,7 @@ internal object AccountCryptoCurrencyStatusFinder {
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun AccountStatusList.getExpectedAccountStatuses(networks: List<Network>): List<AccountStatus> {
|
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
|
if (possibleAccountIndexes.isEmpty()) return accountStatuses
|
||||||
|
|
||||||
|
|
@ -256,16 +256,14 @@ internal object AccountCryptoCurrencyStatusFinder {
|
||||||
// region AccountList helpers
|
// region AccountList helpers
|
||||||
|
|
||||||
internal fun AccountList.getExpectedAccounts(network: Network?): List<Account> {
|
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(
|
private fun AccountList.getExpectedAccounts(
|
||||||
rawNetworkId: String?,
|
rawNetworkId: Network.RawID?,
|
||||||
derivationPath: Network.DerivationPath?,
|
derivationPath: Network.DerivationPath?,
|
||||||
): List<Account> {
|
): List<Account> {
|
||||||
val possibleAccountIndex = getAccountIndexOrNull(rawNetworkId, derivationPath)
|
return when (val possibleAccountIndex = getAccountIndexOrNull(rawNetworkId, derivationPath)) {
|
||||||
|
|
||||||
return when (possibleAccountIndex) {
|
|
||||||
null -> accounts
|
null -> accounts
|
||||||
DerivationIndex.Main.value -> listOf(mainAccount)
|
DerivationIndex.Main.value -> listOf(mainAccount)
|
||||||
// currency only in the account with specific derivation index or in the main account
|
// currency only in the account with specific derivation index or in the main account
|
||||||
|
|
@ -283,10 +281,10 @@ internal object AccountCryptoCurrencyStatusFinder {
|
||||||
|
|
||||||
// region Common helpers
|
// 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
|
if (rawNetworkId == null || derivationPath == null) return null
|
||||||
|
|
||||||
val blockchain = Blockchain.fromId(id = rawNetworkId)
|
val blockchain = rawNetworkId.toBlockchain()
|
||||||
val recognizer = AccountNodeRecognizer(blockchain)
|
val recognizer = AccountNodeRecognizer(blockchain)
|
||||||
|
|
||||||
return recognizer.recognize(derivationPath)?.toInt()
|
return recognizer.recognize(derivationPath)?.toInt()
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ import kotlinx.serialization.Serializable
|
||||||
* (e.g., ERC20, BEP20).
|
* (e.g., ERC20, BEP20).
|
||||||
*
|
*
|
||||||
* @property id the unique identifier of the network
|
* @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 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 currencySymbol the symbol of the currency associated with the network
|
||||||
* @property derivationPath the path used to derive keys for this network
|
* @property derivationPath the path used to derive keys for this network
|
||||||
|
|
@ -25,7 +24,6 @@ import kotlinx.serialization.Serializable
|
||||||
@Serializable
|
@Serializable
|
||||||
data class Network(
|
data class Network(
|
||||||
val id: ID,
|
val id: ID,
|
||||||
val backendId: String,
|
|
||||||
val name: String,
|
val name: String,
|
||||||
val currencySymbol: String,
|
val currencySymbol: String,
|
||||||
val derivationPath: DerivationPath,
|
val derivationPath: DerivationPath,
|
||||||
|
|
@ -37,6 +35,11 @@ data class Network(
|
||||||
val nameResolvingType: NameResolvingType,
|
val nameResolvingType: NameResolvingType,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
/** Backend ID */
|
||||||
|
@Deprecated("Will be removed later")
|
||||||
|
val backendId: String
|
||||||
|
get() = id.rawId.value
|
||||||
|
|
||||||
/** Raw ID */
|
/** Raw ID */
|
||||||
val rawId: String
|
val rawId: String
|
||||||
get() = id.rawId.value
|
get() = id.rawId.value
|
||||||
|
|
|
||||||
|
|
@ -147,7 +147,7 @@ sealed interface StakingIntegrationID {
|
||||||
* @return a [StakingIntegrationID] if supported, or `null` if not supported.
|
* @return a [StakingIntegrationID] if supported, or `null` if not supported.
|
||||||
*/
|
*/
|
||||||
fun create(currencyId: CryptoCurrency.ID): StakingIntegrationID? {
|
fun create(currencyId: CryptoCurrency.ID): StakingIntegrationID? {
|
||||||
val blockchain = Blockchain.fromId(id = currencyId.rawNetworkId)
|
val blockchain = currencyId.toBlockchain()
|
||||||
|
|
||||||
return if (currencyId.contractAddress.isNullOrBlank()) {
|
return if (currencyId.contractAddress.isNullOrBlank()) {
|
||||||
// Order is not important — either P2PEthPool or Stakekit.Coin can be in any order
|
// 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 arrow.core.right
|
||||||
import com.google.common.truth.Truth
|
import com.google.common.truth.Truth
|
||||||
import com.tangem.blockchain.common.Blockchain
|
import com.tangem.blockchain.common.Blockchain
|
||||||
|
import com.tangem.blockchainsdk.utils.toNetworkId
|
||||||
import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory
|
import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory
|
||||||
import com.tangem.domain.models.currency.CryptoCurrency
|
import com.tangem.domain.models.currency.CryptoCurrency
|
||||||
import com.tangem.domain.models.staking.StakingID
|
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.staking.toggles.StakingFeatureToggles
|
||||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||||
import com.tangem.test.core.ProvideTestModels
|
import com.tangem.test.core.ProvideTestModels
|
||||||
import io.mockk.clearMocks
|
import io.mockk.*
|
||||||
import io.mockk.coEvery
|
|
||||||
import io.mockk.coVerify
|
|
||||||
import io.mockk.every
|
|
||||||
import io.mockk.mockk
|
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.jupiter.api.BeforeEach
|
||||||
import org.junit.jupiter.api.Nested
|
import org.junit.jupiter.api.Nested
|
||||||
|
|
@ -188,7 +185,7 @@ internal class StakingIdFactoryTest {
|
||||||
),
|
),
|
||||||
CreateModel(
|
CreateModel(
|
||||||
currencyId = CryptoCurrency.ID.fromValue(
|
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),
|
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>)
|
data class CreateModel(val currencyId: CryptoCurrency.ID, val expected: Either<StakingIdFactory.Error, StakingID>)
|
||||||
|
|
||||||
private fun createCurrencyId(blockchain: Blockchain): CryptoCurrency.ID {
|
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.google.common.truth.Truth
|
||||||
import com.tangem.blockchain.common.Blockchain
|
import com.tangem.blockchain.common.Blockchain
|
||||||
|
import com.tangem.blockchainsdk.utils.toNetworkId
|
||||||
import com.tangem.domain.models.currency.CryptoCurrency
|
import com.tangem.domain.models.currency.CryptoCurrency
|
||||||
import com.tangem.domain.staking.model.StakingApproval
|
import com.tangem.domain.staking.model.StakingApproval
|
||||||
import com.tangem.domain.staking.model.StakingIntegrationID
|
import com.tangem.domain.staking.model.StakingIntegrationID
|
||||||
|
|
@ -144,11 +145,11 @@ class StakingIntegrationIDTest {
|
||||||
expected = StakingIntegrationID.P2PEthPool,
|
expected = StakingIntegrationID.P2PEthPool,
|
||||||
),
|
),
|
||||||
CreateModel(
|
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,
|
expected = StakingIntegrationID.StakeKit.EthereumToken.Polygon,
|
||||||
),
|
),
|
||||||
CreateModel(
|
CreateModel(
|
||||||
currencyId = CryptoCurrency.ID.fromValue(value = "token⟨SOLANA⟩solana⚓1234567890"),
|
currencyId = CryptoCurrency.ID.fromValue(value = "token⟨solana⟩solana⚓1234567890"),
|
||||||
expected = null,
|
expected = null,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
@ -157,6 +158,6 @@ class StakingIntegrationIDTest {
|
||||||
data class CreateModel(val currencyId: CryptoCurrency.ID, val expected: StakingIntegrationID?)
|
data class CreateModel(val currencyId: CryptoCurrency.ID, val expected: StakingIntegrationID?)
|
||||||
|
|
||||||
private fun createCurrencyId(blockchain: Blockchain): CryptoCurrency.ID {
|
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",
|
name = "Network One",
|
||||||
isTestnet = false,
|
isTestnet = false,
|
||||||
standardType = Network.StandardType.ERC20,
|
standardType = Network.StandardType.ERC20,
|
||||||
backendId = "network1",
|
|
||||||
currencySymbol = "ETH",
|
currencySymbol = "ETH",
|
||||||
derivationPath = Network.DerivationPath.None,
|
derivationPath = Network.DerivationPath.None,
|
||||||
hasFiatFeeRate = true,
|
hasFiatFeeRate = true,
|
||||||
|
|
@ -32,7 +31,6 @@ internal object MockNetworks {
|
||||||
name = "Network Two",
|
name = "Network Two",
|
||||||
isTestnet = false,
|
isTestnet = false,
|
||||||
standardType = Network.StandardType.ERC20,
|
standardType = Network.StandardType.ERC20,
|
||||||
backendId = "network1",
|
|
||||||
currencySymbol = "ETH",
|
currencySymbol = "ETH",
|
||||||
derivationPath = Network.DerivationPath.None,
|
derivationPath = Network.DerivationPath.None,
|
||||||
hasFiatFeeRate = true,
|
hasFiatFeeRate = true,
|
||||||
|
|
@ -46,7 +44,6 @@ internal object MockNetworks {
|
||||||
name = "Network Three",
|
name = "Network Three",
|
||||||
isTestnet = false,
|
isTestnet = false,
|
||||||
standardType = Network.StandardType.ERC20,
|
standardType = Network.StandardType.ERC20,
|
||||||
backendId = "network1",
|
|
||||||
currencySymbol = "ETH",
|
currencySymbol = "ETH",
|
||||||
derivationPath = Network.DerivationPath.None,
|
derivationPath = Network.DerivationPath.None,
|
||||||
hasFiatFeeRate = true,
|
hasFiatFeeRate = true,
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ dependencies {
|
||||||
/** Core */
|
/** Core */
|
||||||
implementation(projects.core.ui)
|
implementation(projects.core.ui)
|
||||||
implementation(projects.core.utils)
|
implementation(projects.core.utils)
|
||||||
|
implementation(projects.libs.blockchainSdk)
|
||||||
|
|
||||||
/** Domain */
|
/** Domain */
|
||||||
implementation(projects.domain.account.status)
|
implementation(projects.domain.account.status)
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import arrow.core.Either.Companion.catch
|
||||||
import arrow.core.getOrElse
|
import arrow.core.getOrElse
|
||||||
import com.tangem.blockchain.common.Blockchain
|
import com.tangem.blockchain.common.Blockchain
|
||||||
import com.tangem.blockchain.common.transaction.Fee
|
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.status.utils.CryptoCurrencyOperations.getCoin
|
||||||
import com.tangem.domain.account.supplier.SingleAccountListSupplier
|
import com.tangem.domain.account.supplier.SingleAccountListSupplier
|
||||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||||
|
|
@ -67,8 +68,7 @@ class YieldSupplyGetCurrentFeeUseCase(
|
||||||
|
|
||||||
val tokenValue = rateRatio.multiply(nativeGas.amount.value)
|
val tokenValue = rateRatio.multiply(nativeGas.amount.value)
|
||||||
|
|
||||||
val isEthereum = cryptoCurrencyStatus.currency
|
val isEthereum = cryptoCurrencyStatus.currency.network.rawId == Blockchain.Ethereum.toNetworkId()
|
||||||
.network.id.rawId.value == Blockchain.Ethereum.id
|
|
||||||
|
|
||||||
val isHighFee = if (isEthereum) {
|
val isHighFee = if (isEthereum) {
|
||||||
val maxFeePerGas = (feeWithoutGas as? Fee.Ethereum.EIP1559)?.maxFeePerGas ?: 0.toBigInteger()
|
val maxFeePerGas = (feeWithoutGas as? Fee.Ethereum.EIP1559)?.maxFeePerGas ?: 0.toBigInteger()
|
||||||
|
|
|
||||||
|
|
@ -165,8 +165,7 @@ class YieldSupplyMinAmountUseCaseTest {
|
||||||
private fun createNetwork(): Network {
|
private fun createNetwork(): Network {
|
||||||
val derivationPath = Network.DerivationPath.None
|
val derivationPath = Network.DerivationPath.None
|
||||||
return Network(
|
return Network(
|
||||||
id = Network.ID(Network.RawID("polygon"), derivationPath),
|
id = Network.ID(value = "polygon", derivationPath = derivationPath),
|
||||||
backendId = "polygon",
|
|
||||||
name = "Polygon",
|
name = "Polygon",
|
||||||
currencySymbol = "MATIC",
|
currencySymbol = "MATIC",
|
||||||
derivationPath = derivationPath,
|
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.Network
|
||||||
import com.tangem.domain.models.network.NetworkAddress
|
import com.tangem.domain.models.network.NetworkAddress
|
||||||
import com.tangem.domain.models.wallet.UserWalletId
|
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.models.yield.supply.YieldSupplyStatus
|
||||||
|
import com.tangem.domain.yield.supply.YieldSupplyRepository
|
||||||
import com.tangem.domain.yield.supply.models.YieldSupplyPendingStatus
|
import com.tangem.domain.yield.supply.models.YieldSupplyPendingStatus
|
||||||
import io.mockk.coEvery
|
import io.mockk.coEvery
|
||||||
import io.mockk.coVerify
|
import io.mockk.coVerify
|
||||||
|
|
@ -324,7 +324,6 @@ class YieldSupplyEnterStatusUseCaseTest {
|
||||||
val derivationPath = Network.DerivationPath.None
|
val derivationPath = Network.DerivationPath.None
|
||||||
val network = Network(
|
val network = Network(
|
||||||
id = Network.ID(value = rawNetworkId, derivationPath = derivationPath),
|
id = Network.ID(value = rawNetworkId, derivationPath = derivationPath),
|
||||||
backendId = rawNetworkId,
|
|
||||||
name = rawNetworkId,
|
name = rawNetworkId,
|
||||||
currencySymbol = rawNetworkId.take(3).uppercase(),
|
currencySymbol = rawNetworkId.take(3).uppercase(),
|
||||||
derivationPath = derivationPath,
|
derivationPath = derivationPath,
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package com.tangem.domain.yield.supply.usecase
|
||||||
|
|
||||||
import arrow.core.Either
|
import arrow.core.Either
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import com.tangem.blockchain.common.Blockchain
|
|
||||||
import com.tangem.blockchain.common.transaction.Fee
|
import com.tangem.blockchain.common.transaction.Fee
|
||||||
import com.tangem.domain.account.models.AccountList
|
import com.tangem.domain.account.models.AccountList
|
||||||
import com.tangem.domain.account.supplier.SingleAccountListSupplier
|
import com.tangem.domain.account.supplier.SingleAccountListSupplier
|
||||||
|
|
@ -48,7 +48,7 @@ class YieldSupplyGetCurrentFeeUseCaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `GIVEN valid inputs on non-ethereum WHEN invoke THEN returns fee value and not high`() = runTest {
|
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 tokenDecimals = 8
|
||||||
val nativeDecimals = 18
|
val nativeDecimals = 18
|
||||||
val token = createToken(rawNetworkId = rawNetworkId, decimals = tokenDecimals)
|
val token = createToken(rawNetworkId = rawNetworkId, decimals = tokenDecimals)
|
||||||
|
|
@ -100,7 +100,7 @@ class YieldSupplyGetCurrentFeeUseCaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `GIVEN ethereum with high gas WHEN invoke THEN returns high fee flag`() = runTest {
|
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 tokenDecimals = 8
|
||||||
val nativeDecimals = 18
|
val nativeDecimals = 18
|
||||||
val token = createToken(rawNetworkId = rawNetworkId, decimals = tokenDecimals)
|
val token = createToken(rawNetworkId = rawNetworkId, decimals = tokenDecimals)
|
||||||
|
|
@ -152,7 +152,7 @@ class YieldSupplyGetCurrentFeeUseCaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `GIVEN token fiat rate missing WHEN invoke THEN returns error`() = runTest {
|
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 token = createToken(rawNetworkId = rawNetworkId, decimals = 8)
|
||||||
val cryptoStatus = createStatus(token = token, fiatRate = null)
|
val cryptoStatus = createStatus(token = token, fiatRate = null)
|
||||||
|
|
||||||
|
|
@ -175,7 +175,7 @@ class YieldSupplyGetCurrentFeeUseCaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `GIVEN native quotes unavailable WHEN invoke THEN returns error`() = runTest {
|
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 token = createToken(rawNetworkId = rawNetworkId, decimals = 8)
|
||||||
val cryptoStatus = createStatus(token = token, fiatRate = BigDecimal("2.00"))
|
val cryptoStatus = createStatus(token = token, fiatRate = BigDecimal("2.00"))
|
||||||
val nativeCoin = createCoin(rawNetworkId = rawNetworkId, decimals = 18)
|
val nativeCoin = createCoin(rawNetworkId = rawNetworkId, decimals = 18)
|
||||||
|
|
@ -204,7 +204,7 @@ class YieldSupplyGetCurrentFeeUseCaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `GIVEN empty quotes list WHEN invoke THEN returns error`() = runTest {
|
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 token = createToken(rawNetworkId = rawNetworkId, decimals = 8)
|
||||||
val cryptoStatus = createStatus(token = token, fiatRate = BigDecimal("2.00"))
|
val cryptoStatus = createStatus(token = token, fiatRate = BigDecimal("2.00"))
|
||||||
val nativeCoin = createCoin(rawNetworkId = rawNetworkId, decimals = 18)
|
val nativeCoin = createCoin(rawNetworkId = rawNetworkId, decimals = 18)
|
||||||
|
|
@ -233,7 +233,7 @@ class YieldSupplyGetCurrentFeeUseCaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `GIVEN native fiat rate non-positive WHEN invoke THEN returns error`() = runTest {
|
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 token = createToken(rawNetworkId = rawNetworkId, decimals = 8)
|
||||||
val cryptoStatus = createStatus(token = token, fiatRate = BigDecimal("2.00"))
|
val cryptoStatus = createStatus(token = token, fiatRate = BigDecimal("2.00"))
|
||||||
val nativeCoin = createCoin(rawNetworkId = rawNetworkId, decimals = 18)
|
val nativeCoin = createCoin(rawNetworkId = rawNetworkId, decimals = 18)
|
||||||
|
|
@ -274,7 +274,7 @@ class YieldSupplyGetCurrentFeeUseCaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `GIVEN token fiat rate non-positive WHEN invoke THEN returns error`() = runTest {
|
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 token = createToken(rawNetworkId = rawNetworkId, decimals = 8)
|
||||||
val cryptoStatus = createStatus(token = token, fiatRate = BigDecimal.ZERO) // non-positive
|
val cryptoStatus = createStatus(token = token, fiatRate = BigDecimal.ZERO) // non-positive
|
||||||
|
|
||||||
|
|
@ -299,7 +299,6 @@ class YieldSupplyGetCurrentFeeUseCaseTest {
|
||||||
val derivationPath = Network.DerivationPath.None
|
val derivationPath = Network.DerivationPath.None
|
||||||
val network = Network(
|
val network = Network(
|
||||||
id = Network.ID(value = rawNetworkId, derivationPath = derivationPath),
|
id = Network.ID(value = rawNetworkId, derivationPath = derivationPath),
|
||||||
backendId = rawNetworkId,
|
|
||||||
name = rawNetworkId,
|
name = rawNetworkId,
|
||||||
currencySymbol = rawNetworkId.take(3).uppercase(),
|
currencySymbol = rawNetworkId.take(3).uppercase(),
|
||||||
derivationPath = derivationPath,
|
derivationPath = derivationPath,
|
||||||
|
|
@ -331,7 +330,6 @@ class YieldSupplyGetCurrentFeeUseCaseTest {
|
||||||
val derivationPath = Network.DerivationPath.None
|
val derivationPath = Network.DerivationPath.None
|
||||||
val network = Network(
|
val network = Network(
|
||||||
id = Network.ID(value = rawNetworkId, derivationPath = derivationPath),
|
id = Network.ID(value = rawNetworkId, derivationPath = derivationPath),
|
||||||
backendId = rawNetworkId,
|
|
||||||
name = rawNetworkId,
|
name = rawNetworkId,
|
||||||
currencySymbol = rawNetworkId.take(3).uppercase(),
|
currencySymbol = rawNetworkId.take(3).uppercase(),
|
||||||
derivationPath = derivationPath,
|
derivationPath = derivationPath,
|
||||||
|
|
|
||||||
|
|
@ -61,8 +61,7 @@ class YieldSupplyGetDustMinAmountUseCaseTest {
|
||||||
private fun createNetwork(): Network {
|
private fun createNetwork(): Network {
|
||||||
val derivationPath = Network.DerivationPath.None
|
val derivationPath = Network.DerivationPath.None
|
||||||
return Network(
|
return Network(
|
||||||
id = Network.ID(Network.RawID("polygon"), derivationPath),
|
id = Network.ID(value = "polygon", derivationPath = derivationPath),
|
||||||
backendId = "polygon",
|
|
||||||
name = "Polygon",
|
name = "Polygon",
|
||||||
currencySymbol = "MATIC",
|
currencySymbol = "MATIC",
|
||||||
derivationPath = derivationPath,
|
derivationPath = derivationPath,
|
||||||
|
|
|
||||||
|
|
@ -238,8 +238,7 @@ class YieldSupplyGetRewardsBalanceUseCaseTest {
|
||||||
@Test
|
@Test
|
||||||
fun `GIVEN polygon USDT0 Loaded status WHEN invoke THEN emit formatted balances`() = runTest {
|
fun `GIVEN polygon USDT0 Loaded status WHEN invoke THEN emit formatted balances`() = runTest {
|
||||||
val network = Network(
|
val network = Network(
|
||||||
id = Network.ID(Network.RawID("POLYGON"), Network.DerivationPath.Card("m/44'/60'/0'/0/0")),
|
id = Network.ID(value = "polygon-pos", derivationPath = Network.DerivationPath.Card("m/44'/60'/0'/0/0")),
|
||||||
backendId = "polygon-pos",
|
|
||||||
name = "Polygon",
|
name = "Polygon",
|
||||||
currencySymbol = "POL",
|
currencySymbol = "POL",
|
||||||
derivationPath = Network.DerivationPath.Card("m/44'/60'/0'/0/0"),
|
derivationPath = Network.DerivationPath.Card("m/44'/60'/0'/0/0"),
|
||||||
|
|
@ -365,8 +364,7 @@ class YieldSupplyGetRewardsBalanceUseCaseTest {
|
||||||
private fun createNetwork(): Network {
|
private fun createNetwork(): Network {
|
||||||
val derivationPath = Network.DerivationPath.None
|
val derivationPath = Network.DerivationPath.None
|
||||||
return Network(
|
return Network(
|
||||||
id = Network.ID(Network.RawID("polygon"), derivationPath),
|
id = Network.ID(value = "polygon", derivationPath = derivationPath),
|
||||||
backendId = "polygon",
|
|
||||||
name = "Polygon",
|
name = "Polygon",
|
||||||
currencySymbol = "MATIC",
|
currencySymbol = "MATIC",
|
||||||
derivationPath = derivationPath,
|
derivationPath = derivationPath,
|
||||||
|
|
|
||||||
|
|
@ -279,7 +279,6 @@ class YieldSupplyPendingTrackerTest {
|
||||||
val derivationPath = Network.DerivationPath.None
|
val derivationPath = Network.DerivationPath.None
|
||||||
val network = Network(
|
val network = Network(
|
||||||
id = Network.ID(value = networkId, derivationPath = derivationPath),
|
id = Network.ID(value = networkId, derivationPath = derivationPath),
|
||||||
backendId = networkId,
|
|
||||||
name = networkId,
|
name = networkId,
|
||||||
currencySymbol = networkId.take(3).uppercase(),
|
currencySymbol = networkId.take(3).uppercase(),
|
||||||
derivationPath = derivationPath,
|
derivationPath = derivationPath,
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,6 @@ internal class PreviewCustomTokenSelectorComponent(
|
||||||
CurrencyNetworkUM(
|
CurrencyNetworkUM(
|
||||||
network = Network(
|
network = Network(
|
||||||
id = n.id,
|
id = n.id,
|
||||||
backendId = n.id.rawId.value,
|
|
||||||
name = "Network $index",
|
name = "Network $index",
|
||||||
currencySymbol = "N$index",
|
currencySymbol = "N$index",
|
||||||
derivationPath = Network.DerivationPath.Card(""),
|
derivationPath = Network.DerivationPath.Card(""),
|
||||||
|
|
|
||||||
|
|
@ -154,7 +154,6 @@ internal class PreviewManageTokensComponent(
|
||||||
CurrencyNetworkUM(
|
CurrencyNetworkUM(
|
||||||
network = Network(
|
network = Network(
|
||||||
id = Network.ID(value = networkIndex.toString(), derivationPath = derivationPath),
|
id = Network.ID(value = networkIndex.toString(), derivationPath = derivationPath),
|
||||||
backendId = networkIndex.toString(),
|
|
||||||
name = "Network $networkIndex",
|
name = "Network $networkIndex",
|
||||||
currencySymbol = "N$networkIndex",
|
currencySymbol = "N$networkIndex",
|
||||||
derivationPath = derivationPath,
|
derivationPath = derivationPath,
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,6 @@ internal class PreviewOnboardingManageTokensComponent(
|
||||||
CurrencyNetworkUM(
|
CurrencyNetworkUM(
|
||||||
network = Network(
|
network = Network(
|
||||||
id = Network.ID(value = networkIndex.toString(), derivationPath = derivationPath),
|
id = Network.ID(value = networkIndex.toString(), derivationPath = derivationPath),
|
||||||
backendId = networkIndex.toString(),
|
|
||||||
name = "Network $networkIndex",
|
name = "Network $networkIndex",
|
||||||
currencySymbol = "N$networkIndex",
|
currencySymbol = "N$networkIndex",
|
||||||
derivationPath = derivationPath,
|
derivationPath = derivationPath,
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ package com.tangem.features.managetokens.model
|
||||||
import arrow.core.getOrElse
|
import arrow.core.getOrElse
|
||||||
import com.arkivanov.decompose.router.slot.SlotNavigation
|
import com.arkivanov.decompose.router.slot.SlotNavigation
|
||||||
import com.arkivanov.decompose.router.slot.activate
|
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.common.ui.account.toUM
|
||||||
import com.tangem.core.decompose.di.ModelScoped
|
import com.tangem.core.decompose.di.ModelScoped
|
||||||
import com.tangem.core.decompose.model.Model
|
import com.tangem.core.decompose.model.Model
|
||||||
|
|
@ -199,7 +199,7 @@ internal class CustomTokenSelectorModel @Inject constructor(
|
||||||
private fun DerivationPathSelector.checkAccountDerivation(derivationPath: SelectedDerivationPath) =
|
private fun DerivationPathSelector.checkAccountDerivation(derivationPath: SelectedDerivationPath) =
|
||||||
modelScope.launch {
|
modelScope.launch {
|
||||||
val account = derivationPath.id
|
val account = derivationPath.id
|
||||||
?.let { Blockchain.fromId(it.rawId.value) }
|
?.toBlockchain()
|
||||||
?.let(::AccountNodeRecognizer)
|
?.let(::AccountNodeRecognizer)
|
||||||
?.let { recognizer ->
|
?.let { recognizer ->
|
||||||
val derivationPathValue = derivationPath.value.value
|
val derivationPathValue = derivationPath.value.value
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,6 @@ private fun Preview() {
|
||||||
value = "bitcoin",
|
value = "bitcoin",
|
||||||
derivationPath = Network.DerivationPath.None,
|
derivationPath = Network.DerivationPath.None,
|
||||||
),
|
),
|
||||||
backendId = "bitcoin",
|
|
||||||
name = "Bitcoin",
|
name = "Bitcoin",
|
||||||
currencySymbol = "BTC",
|
currencySymbol = "BTC",
|
||||||
derivationPath = Network.DerivationPath.None,
|
derivationPath = Network.DerivationPath.None,
|
||||||
|
|
|
||||||
|
|
@ -516,7 +516,6 @@ private val cryptoCurrencyStatus
|
||||||
value = "bitcoin",
|
value = "bitcoin",
|
||||||
derivationPath = Network.DerivationPath.None,
|
derivationPath = Network.DerivationPath.None,
|
||||||
),
|
),
|
||||||
backendId = "bitcoin",
|
|
||||||
name = "Bitcoin",
|
name = "Bitcoin",
|
||||||
currencySymbol = "BTC",
|
currencySymbol = "BTC",
|
||||||
derivationPath = Network.DerivationPath.None,
|
derivationPath = Network.DerivationPath.None,
|
||||||
|
|
|
||||||
|
|
@ -171,7 +171,6 @@ private fun Preview() {
|
||||||
value = "bitcoin",
|
value = "bitcoin",
|
||||||
derivationPath = Network.DerivationPath.None,
|
derivationPath = Network.DerivationPath.None,
|
||||||
),
|
),
|
||||||
backendId = "bitcoin",
|
|
||||||
name = "Bitcoin",
|
name = "Bitcoin",
|
||||||
currencySymbol = "BTC",
|
currencySymbol = "BTC",
|
||||||
derivationPath = Network.DerivationPath.None,
|
derivationPath = Network.DerivationPath.None,
|
||||||
|
|
|
||||||
|
|
@ -258,7 +258,6 @@ private class FeeSelectorUMProvider : PreviewParameterProvider<FeeSelectorUM> {
|
||||||
value = "bitcoin",
|
value = "bitcoin",
|
||||||
derivationPath = Network.DerivationPath.None,
|
derivationPath = Network.DerivationPath.None,
|
||||||
),
|
),
|
||||||
backendId = "bitcoin",
|
|
||||||
name = "Bitcoin",
|
name = "Bitcoin",
|
||||||
currencySymbol = "BTC",
|
currencySymbol = "BTC",
|
||||||
derivationPath = Network.DerivationPath.None,
|
derivationPath = Network.DerivationPath.None,
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ class NFTSendConfirmationNotificationsTransformerV2Test {
|
||||||
private val appCurrency = AppCurrency(name = "US Dollar", code = "USD", symbol = "$")
|
private val appCurrency = AppCurrency(name = "US Dollar", code = "USD", symbol = "$")
|
||||||
private val analyticsCategoryName = "test_category"
|
private val analyticsCategoryName = "test_category"
|
||||||
|
|
||||||
val cryptoCurrencyStatus = CryptoCurrencyStatus(
|
private val cryptoCurrencyStatus = CryptoCurrencyStatus(
|
||||||
currency = CryptoCurrency.Coin(
|
currency = CryptoCurrency.Coin(
|
||||||
id = CryptoCurrency.ID.fromValue("coin⟨BITCOIN⟩bitcoin"),
|
id = CryptoCurrency.ID.fromValue("coin⟨BITCOIN⟩bitcoin"),
|
||||||
network = Network(
|
network = Network(
|
||||||
|
|
@ -38,7 +38,6 @@ class NFTSendConfirmationNotificationsTransformerV2Test {
|
||||||
value = "bitcoin",
|
value = "bitcoin",
|
||||||
derivationPath = Network.DerivationPath.None,
|
derivationPath = Network.DerivationPath.None,
|
||||||
),
|
),
|
||||||
backendId = "bitcoin",
|
|
||||||
name = "Bitcoin",
|
name = "Bitcoin",
|
||||||
currencySymbol = "BTC",
|
currencySymbol = "BTC",
|
||||||
derivationPath = Network.DerivationPath.None,
|
derivationPath = Network.DerivationPath.None,
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ class SendConfirmationNotificationsTransformerV2Test {
|
||||||
private val appCurrency = AppCurrency(name = "US Dollar", code = "USD", symbol = "$")
|
private val appCurrency = AppCurrency(name = "US Dollar", code = "USD", symbol = "$")
|
||||||
private val analyticsCategoryName = "test_category"
|
private val analyticsCategoryName = "test_category"
|
||||||
|
|
||||||
val cryptoCurrencyStatus = CryptoCurrencyStatus(
|
private val cryptoCurrencyStatus = CryptoCurrencyStatus(
|
||||||
currency = CryptoCurrency.Coin(
|
currency = CryptoCurrency.Coin(
|
||||||
id = CryptoCurrency.ID.fromValue("coin⟨BITCOIN⟩bitcoin"),
|
id = CryptoCurrency.ID.fromValue("coin⟨BITCOIN⟩bitcoin"),
|
||||||
network = Network(
|
network = Network(
|
||||||
|
|
@ -40,7 +40,6 @@ class SendConfirmationNotificationsTransformerV2Test {
|
||||||
value = "bitcoin",
|
value = "bitcoin",
|
||||||
derivationPath = Network.DerivationPath.None,
|
derivationPath = Network.DerivationPath.None,
|
||||||
),
|
),
|
||||||
backendId = "bitcoin",
|
|
||||||
name = "Bitcoin",
|
name = "Bitcoin",
|
||||||
currencySymbol = "BTC",
|
currencySymbol = "BTC",
|
||||||
derivationPath = Network.DerivationPath.None,
|
derivationPath = Network.DerivationPath.None,
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,6 @@ internal data object SwapAmountContentPreview {
|
||||||
value = "bitcoin",
|
value = "bitcoin",
|
||||||
derivationPath = Network.DerivationPath.None,
|
derivationPath = Network.DerivationPath.None,
|
||||||
),
|
),
|
||||||
backendId = "bitcoin",
|
|
||||||
name = "Bitcoin",
|
name = "Bitcoin",
|
||||||
currencySymbol = "BTC",
|
currencySymbol = "BTC",
|
||||||
derivationPath = Network.DerivationPath.None,
|
derivationPath = Network.DerivationPath.None,
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,6 @@ class ExpressStatusBottomSheetStateProvider : PreviewParameterProvider<ExpressSt
|
||||||
name = "Network One",
|
name = "Network One",
|
||||||
isTestnet = false,
|
isTestnet = false,
|
||||||
standardType = Network.StandardType.ERC20,
|
standardType = Network.StandardType.ERC20,
|
||||||
backendId = "network1",
|
|
||||||
currencySymbol = "ETH",
|
currencySymbol = "ETH",
|
||||||
derivationPath = Network.DerivationPath.None,
|
derivationPath = Network.DerivationPath.None,
|
||||||
hasFiatFeeRate = true,
|
hasFiatFeeRate = true,
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ class YieldSupplyPromoBannerConverterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `GIVEN promo disabled WHEN convert THEN return null`() {
|
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 status = createLoadedStatus(token = token, amount = BigDecimal.ONE, isYieldActive = false)
|
||||||
val tokenList = ungroupedTokenList(status)
|
val tokenList = ungroupedTokenList(status)
|
||||||
val params = TokenConverterParams.Wallet(
|
val params = TokenConverterParams.Wallet(
|
||||||
|
|
@ -46,7 +46,7 @@ class YieldSupplyPromoBannerConverterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `GIVEN empty apy map WHEN convert THEN return null`() {
|
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 status = createLoadedStatus(token = token, amount = BigDecimal("2.0"), isYieldActive = false)
|
||||||
val params = TokenConverterParams.Wallet(
|
val params = TokenConverterParams.Wallet(
|
||||||
mainAccount = account,
|
mainAccount = account,
|
||||||
|
|
@ -64,7 +64,7 @@ class YieldSupplyPromoBannerConverterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `GIVEN active yield token present WHEN convert THEN return null`() {
|
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 statusActive = createLoadedStatus(token = token, amount = BigDecimal("5"), isYieldActive = true)
|
||||||
val params = TokenConverterParams.Wallet(
|
val params = TokenConverterParams.Wallet(
|
||||||
mainAccount = account,
|
mainAccount = account,
|
||||||
|
|
@ -82,9 +82,9 @@ class YieldSupplyPromoBannerConverterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `GIVEN multiple candidates EVM case insensitive WHEN convert THEN return status of max amount`() {
|
fun `GIVEN multiple candidates EVM case insensitive WHEN convert THEN return status of max amount`() {
|
||||||
val evmNetworkId = "ETH"
|
val evmNetworkId = "ethereum"
|
||||||
val tokenSmall = createToken(networkId = evmNetworkId, backendId = evmNetworkId, contract = "0xAbCd")
|
val tokenSmall = createToken(networkId = evmNetworkId, rawId = evmNetworkId, contract = "0xAbCd")
|
||||||
val tokenBig = createToken(networkId = evmNetworkId, backendId = evmNetworkId, contract = "0xBEEF")
|
val tokenBig = createToken(networkId = evmNetworkId, rawId = evmNetworkId, contract = "0xBEEF")
|
||||||
|
|
||||||
val statusSmall = createLoadedStatus(token = tokenSmall, amount = BigDecimal("1.00"), isYieldActive = false)
|
val statusSmall = createLoadedStatus(token = tokenSmall, amount = BigDecimal("1.00"), isYieldActive = false)
|
||||||
val statusBig = createLoadedStatus(token = tokenBig, amount = BigDecimal("10.00"), isYieldActive = false)
|
val statusBig = createLoadedStatus(token = tokenBig, amount = BigDecimal("10.00"), isYieldActive = false)
|
||||||
|
|
@ -111,7 +111,7 @@ class YieldSupplyPromoBannerConverterTest {
|
||||||
@Test
|
@Test
|
||||||
fun `GIVEN non evm case sensitive mismatch WHEN convert THEN return null`() {
|
fun `GIVEN non evm case sensitive mismatch WHEN convert THEN return null`() {
|
||||||
val nonEvmId = "xrp"
|
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 status = createLoadedStatus(token = token, amount = BigDecimal("3"), isYieldActive = false)
|
||||||
|
|
||||||
val mismatchedKey = "${token.network.backendId}_${token.contractAddress.lowercase()}"
|
val mismatchedKey = "${token.network.backendId}_${token.contractAddress.lowercase()}"
|
||||||
|
|
@ -133,7 +133,7 @@ class YieldSupplyPromoBannerConverterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `GIVEN custom status WHEN convert THEN return null`() {
|
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 status = createCustomStatus(token = token, amount = BigDecimal("5.0"), isYieldActive = false)
|
||||||
val params = TokenConverterParams.Wallet(
|
val params = TokenConverterParams.Wallet(
|
||||||
mainAccount = account,
|
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(
|
val network = Network(
|
||||||
id = Network.ID(value = networkId, derivationPath = Network.DerivationPath.None),
|
id = Network.ID(value = rawId, derivationPath = Network.DerivationPath.None),
|
||||||
backendId = backendId,
|
name = rawId,
|
||||||
name = backendId,
|
|
||||||
currencySymbol = "SYM",
|
currencySymbol = "SYM",
|
||||||
derivationPath = Network.DerivationPath.None,
|
derivationPath = Network.DerivationPath.None,
|
||||||
isTestnet = false,
|
isTestnet = false,
|
||||||
standardType = when (backendId) {
|
standardType = when (rawId) {
|
||||||
"ethereum" -> Network.StandardType.ERC20
|
"ethereum" -> Network.StandardType.ERC20
|
||||||
else -> Network.StandardType.Unspecified("UNSPEC")
|
else -> Network.StandardType.Unspecified("UNSPEC")
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -834,10 +834,9 @@ class DefaultPromoDeeplinkHandlerTest {
|
||||||
address: String,
|
address: String,
|
||||||
derivationPath: Network.DerivationPath = Network.DerivationPath.None,
|
derivationPath: Network.DerivationPath = Network.DerivationPath.None,
|
||||||
): NetworkStatus {
|
): NetworkStatus {
|
||||||
val networkId = Network.ID(Network.RawID(rawNetworkId), derivationPath)
|
val networkId = Network.ID(value = rawNetworkId, derivationPath = derivationPath)
|
||||||
val network = Network(
|
val network = Network(
|
||||||
id = networkId,
|
id = networkId,
|
||||||
backendId = rawNetworkId,
|
|
||||||
name = rawNetworkId,
|
name = rawNetworkId,
|
||||||
currencySymbol = rawNetworkId.take(3).uppercase(),
|
currencySymbol = rawNetworkId.take(3).uppercase(),
|
||||||
derivationPath = derivationPath,
|
derivationPath = derivationPath,
|
||||||
|
|
@ -866,10 +865,9 @@ class DefaultPromoDeeplinkHandlerTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildUnreachableNetworkStatus(rawNetworkId: String): NetworkStatus {
|
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(
|
val network = Network(
|
||||||
id = networkId,
|
id = networkId,
|
||||||
backendId = rawNetworkId,
|
|
||||||
name = rawNetworkId,
|
name = rawNetworkId,
|
||||||
currencySymbol = rawNetworkId.take(3).uppercase(),
|
currencySymbol = rawNetworkId.take(3).uppercase(),
|
||||||
derivationPath = Network.DerivationPath.None,
|
derivationPath = Network.DerivationPath.None,
|
||||||
|
|
@ -890,10 +888,9 @@ class DefaultPromoDeeplinkHandlerTest {
|
||||||
rawNetworkId: String,
|
rawNetworkId: String,
|
||||||
derivationPath: Network.DerivationPath = Network.DerivationPath.None,
|
derivationPath: Network.DerivationPath = Network.DerivationPath.None,
|
||||||
): CryptoCurrency.Coin {
|
): CryptoCurrency.Coin {
|
||||||
val networkId = Network.ID(Network.RawID(rawNetworkId), derivationPath)
|
val networkId = Network.ID(value = rawNetworkId, derivationPath = derivationPath)
|
||||||
val network = Network(
|
val network = Network(
|
||||||
id = networkId,
|
id = networkId,
|
||||||
backendId = rawNetworkId,
|
|
||||||
name = rawNetworkId,
|
name = rawNetworkId,
|
||||||
currencySymbol = rawNetworkId.take(3).uppercase(),
|
currencySymbol = rawNetworkId.take(3).uppercase(),
|
||||||
derivationPath = derivationPath,
|
derivationPath = derivationPath,
|
||||||
|
|
|
||||||
|
|
@ -285,8 +285,7 @@ internal class QrContentClassifierTest {
|
||||||
|
|
||||||
private fun buildNetwork(rawNetworkId: String): Network {
|
private fun buildNetwork(rawNetworkId: String): Network {
|
||||||
return Network(
|
return Network(
|
||||||
id = Network.ID(Network.RawID(rawNetworkId), Network.DerivationPath.None),
|
id = Network.ID(value = rawNetworkId, derivationPath = Network.DerivationPath.None),
|
||||||
backendId = rawNetworkId,
|
|
||||||
name = rawNetworkId,
|
name = rawNetworkId,
|
||||||
currencySymbol = rawNetworkId.take(3).uppercase(),
|
currencySymbol = rawNetworkId.take(3).uppercase(),
|
||||||
derivationPath = Network.DerivationPath.None,
|
derivationPath = Network.DerivationPath.None,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package com.tangem.blockchainsdk.utils
|
package com.tangem.blockchainsdk.utils
|
||||||
|
|
||||||
import com.tangem.blockchain.common.Blockchain
|
import com.tangem.blockchain.common.Blockchain
|
||||||
|
import com.tangem.domain.models.currency.CryptoCurrency
|
||||||
import com.tangem.domain.models.network.Network
|
import com.tangem.domain.models.network.Network
|
||||||
|
|
||||||
/** Converts [Network] to [Blockchain] */
|
/** Converts [Network] to [Blockchain] */
|
||||||
|
|
@ -10,4 +11,8 @@ fun Network.toBlockchain(): Blockchain = id.toBlockchain()
|
||||||
fun Network.ID.toBlockchain(): Blockchain = rawId.toBlockchain()
|
fun Network.ID.toBlockchain(): Blockchain = rawId.toBlockchain()
|
||||||
|
|
||||||
/** Converts [Network.RawID] to [Blockchain] */
|
/** 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 */
|
/** Decodes XRP Blockchain address */
|
||||||
fun decodeRippleXAddress(xAddress: String, blockchainId: String): XrpTaggedAddress? {
|
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)
|
val decodedAddress = XrpAddressService.decodeXAddress(xAddress)
|
||||||
return decodedAddress?.let(XrpTaggedAddressConverter()::convert)
|
decodedAddress?.let(XrpTaggedAddressConverter()::convert)
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
@ -38,46 +38,46 @@ object BlockchainUtils {
|
||||||
|
|
||||||
/** If current [networkId] is Bitcoin */
|
/** If current [networkId] is Bitcoin */
|
||||||
fun isBitcoin(blockchainId: String): Boolean {
|
fun isBitcoin(blockchainId: String): Boolean {
|
||||||
val blockchain = Blockchain.fromId(blockchainId)
|
val blockchain = blockchainId.toBlockchain()
|
||||||
return blockchain == Blockchain.Bitcoin || blockchain == Blockchain.BitcoinTestnet
|
return blockchain == Blockchain.Bitcoin || blockchain == Blockchain.BitcoinTestnet
|
||||||
}
|
}
|
||||||
|
|
||||||
/** If current [networkId] is use custom fee */
|
/** If current [networkId] is use custom fee */
|
||||||
fun isUseBitcoinFeeConverter(blockchainId: String): Boolean {
|
fun isUseBitcoinFeeConverter(blockchainId: String): Boolean {
|
||||||
val blockchain = Blockchain.fromId(blockchainId)
|
val blockchain = blockchainId.toBlockchain()
|
||||||
return isBitcoin(blockchainId) || blockchain == Blockchain.Fact0rn
|
return isBitcoin(blockchainId) || blockchain == Blockchain.Fact0rn
|
||||||
}
|
}
|
||||||
|
|
||||||
/** If current [blockchainId] is Tezos */
|
/** If current [blockchainId] is Tezos */
|
||||||
fun isTezos(blockchainId: String): Boolean {
|
fun isTezos(blockchainId: String): Boolean {
|
||||||
val blockchain = Blockchain.fromId(blockchainId)
|
val blockchain = blockchainId.toBlockchain()
|
||||||
return blockchain == Blockchain.Tezos
|
return blockchain == Blockchain.Tezos
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isCardano(blockchainId: String): Boolean {
|
fun isCardano(blockchainId: String): Boolean {
|
||||||
val blockchain = Blockchain.fromId(blockchainId)
|
val blockchain = blockchainId.toBlockchain()
|
||||||
return blockchain == Blockchain.Cardano
|
return blockchain == Blockchain.Cardano
|
||||||
}
|
}
|
||||||
|
|
||||||
/** If current [blockchainId] is BeaconChain */
|
/** If current [blockchainId] is BeaconChain */
|
||||||
fun isBeaconChain(blockchainId: String): Boolean {
|
fun isBeaconChain(blockchainId: String): Boolean {
|
||||||
val blockchain = Blockchain.fromId(blockchainId)
|
val blockchain = blockchainId.toBlockchain()
|
||||||
return blockchain == Blockchain.Binance || blockchain == Blockchain.BinanceTestnet
|
return blockchain == Blockchain.Binance || blockchain == Blockchain.BinanceTestnet
|
||||||
}
|
}
|
||||||
|
|
||||||
/** If current [blockchainId] is Polygon */
|
/** If current [blockchainId] is Polygon */
|
||||||
fun isPolygonChain(blockchainId: String): Boolean {
|
fun isPolygonChain(blockchainId: String): Boolean {
|
||||||
val blockchain = Blockchain.fromId(blockchainId)
|
val blockchain = blockchainId.toBlockchain()
|
||||||
return blockchain == Blockchain.Polygon || blockchain == Blockchain.PolygonTestnet
|
return blockchain == Blockchain.Polygon || blockchain == Blockchain.PolygonTestnet
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isTron(blockchainId: String): Boolean {
|
fun isTron(blockchainId: String): Boolean {
|
||||||
val blockchain = Blockchain.fromId(blockchainId)
|
val blockchain = blockchainId.toBlockchain()
|
||||||
return blockchain == Blockchain.Tron || blockchain == Blockchain.TronTestnet
|
return blockchain == Blockchain.Tron || blockchain == Blockchain.TronTestnet
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isTon(blockchainId: String): Boolean {
|
fun isTon(blockchainId: String): Boolean {
|
||||||
val blockchain = Blockchain.fromId(blockchainId)
|
val blockchain = blockchainId.toBlockchain()
|
||||||
return blockchain == Blockchain.TON || blockchain == Blockchain.TONTestnet
|
return blockchain == Blockchain.TON || blockchain == Blockchain.TONTestnet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -89,7 +89,7 @@ object BlockchainUtils {
|
||||||
coinId: String? = null,
|
coinId: String? = null,
|
||||||
contractAddress: String? = null,
|
contractAddress: String? = null,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val blockchain = Blockchain.fromNetworkId(blockchainId) ?: return false
|
val blockchain = blockchainId.toBlockchain() ?: return false
|
||||||
|
|
||||||
if (blockchain in excludedBlockchains) return false
|
if (blockchain in excludedBlockchains) return false
|
||||||
if (hasOnlyHotWallets && blockchain in hotExcludedBlockchains) return false
|
if (hasOnlyHotWallets && blockchain in hotExcludedBlockchains) return false
|
||||||
|
|
@ -103,37 +103,37 @@ object BlockchainUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isArbitrum(blockchainId: String): Boolean {
|
fun isArbitrum(blockchainId: String): Boolean {
|
||||||
val blockchain = Blockchain.fromId(blockchainId)
|
val blockchain = blockchainId.toBlockchain()
|
||||||
return blockchain == Blockchain.Arbitrum
|
return blockchain == Blockchain.Arbitrum
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isSolana(blockchainId: String): Boolean {
|
fun isSolana(blockchainId: String): Boolean {
|
||||||
val blockchain = Blockchain.fromId(blockchainId)
|
val blockchain = blockchainId.toBlockchain()
|
||||||
return blockchain == Blockchain.Solana
|
return blockchain == Blockchain.Solana
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isPolkadot(blockchainId: String): Boolean {
|
fun isPolkadot(blockchainId: String): Boolean {
|
||||||
val blockchain = Blockchain.fromId(blockchainId)
|
val blockchain = blockchainId.toBlockchain()
|
||||||
return blockchain == Blockchain.Polkadot || blockchain == Blockchain.PolkadotTestnet
|
return blockchain == Blockchain.Polkadot || blockchain == Blockchain.PolkadotTestnet
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isCosmos(blockchainId: String): Boolean {
|
fun isCosmos(blockchainId: String): Boolean {
|
||||||
val blockchain = Blockchain.fromId(blockchainId)
|
val blockchain = blockchainId.toBlockchain()
|
||||||
return blockchain == Blockchain.Cosmos || blockchain == Blockchain.CosmosTestnet
|
return blockchain == Blockchain.Cosmos || blockchain == Blockchain.CosmosTestnet
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isBSC(blockchainId: String): Boolean {
|
fun isBSC(blockchainId: String): Boolean {
|
||||||
val blockchain = Blockchain.fromId(blockchainId)
|
val blockchain = blockchainId.toBlockchain()
|
||||||
return blockchain == Blockchain.BSC || blockchain == Blockchain.BSCTestnet
|
return blockchain == Blockchain.BSC || blockchain == Blockchain.BSCTestnet
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isEthereum(blockchainId: String): Boolean {
|
fun isEthereum(blockchainId: String): Boolean {
|
||||||
val blockchain = Blockchain.fromId(blockchainId)
|
val blockchain = blockchainId.toBlockchain()
|
||||||
return blockchain == Blockchain.Ethereum || blockchain == Blockchain.EthereumTestnet
|
return blockchain == Blockchain.Ethereum || blockchain == Blockchain.EthereumTestnet
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isClore(blockchainId: String): Boolean {
|
fun isClore(blockchainId: String): Boolean {
|
||||||
return Blockchain.fromId(blockchainId) == Blockchain.Clore
|
return blockchainId.toBlockchain() == Blockchain.Clore
|
||||||
}
|
}
|
||||||
|
|
||||||
data class BlockchainInfo(
|
data class BlockchainInfo(
|
||||||
|
|
@ -163,7 +163,7 @@ object BlockchainUtils {
|
||||||
* Blockchains not affecting total balance counting on errors
|
* Blockchains not affecting total balance counting on errors
|
||||||
*/
|
*/
|
||||||
fun isIncludeToBalanceOnError(blockchainId: String): Boolean {
|
fun isIncludeToBalanceOnError(blockchainId: String): Boolean {
|
||||||
val blockchain = Blockchain.fromId(blockchainId)
|
val blockchain = blockchainId.toBlockchain()
|
||||||
return when (blockchain) {
|
return when (blockchain) {
|
||||||
Blockchain.Binance, Blockchain.BinanceTestnet -> true
|
Blockchain.Binance, Blockchain.BinanceTestnet -> true
|
||||||
else -> false
|
else -> false
|
||||||
|
|
@ -171,7 +171,7 @@ object BlockchainUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isIncludeStakingTotalBalance(blockchainId: String): Boolean {
|
fun isIncludeStakingTotalBalance(blockchainId: String): Boolean {
|
||||||
val blockchain = Blockchain.fromId(blockchainId)
|
val blockchain = blockchainId.toBlockchain()
|
||||||
|
|
||||||
return blockchain != Blockchain.Cardano
|
return blockchain != Blockchain.Cardano
|
||||||
}
|
}
|
||||||
|
|
@ -184,9 +184,9 @@ object BlockchainUtils {
|
||||||
|
|
||||||
/** Checks if the blockchain uses case-insensitive contract addresses */
|
/** Checks if the blockchain uses case-insensitive contract addresses */
|
||||||
fun isCaseInsensitiveContractAddress(blockchainId: String): Boolean {
|
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 {
|
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.
|
* 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 {
|
fun isTetherInEthereum(blockchainId: String, contractAddress: String): Boolean {
|
||||||
val blockchain = Blockchain.fromId(blockchainId)
|
val blockchain = blockchainId.toBlockchain()
|
||||||
return (blockchain == Blockchain.Ethereum || blockchain == Blockchain.EthereumTestnet) &&
|
return (blockchain == Blockchain.Ethereum || blockchain == Blockchain.EthereumTestnet) &&
|
||||||
contractAddress.equals(TETHER_CONTRACT_ADDRESS, ignoreCase = true)
|
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