Updated on 2026-08-14

This commit is contained in:
Tangem 2025-05-22 15:49:27 +04:00
parent bf0a66f183
commit 68c7028380
2 changed files with 807 additions and 0 deletions

View file

@ -0,0 +1,339 @@
package com.tangem.data.common.network
import androidx.annotation.VisibleForTesting
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.FeePaidCurrency
import com.tangem.blockchainsdk.utils.ExcludedBlockchains
import com.tangem.blockchainsdk.utils.toNetworkId
import com.tangem.data.common.currency.getBlockchain
import com.tangem.domain.common.DerivationStyleProvider
import com.tangem.domain.common.extensions.canHandleToken
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.domain.common.util.derivationStyleProvider
import com.tangem.domain.models.network.Network
import com.tangem.domain.models.scan.ScanResponse
import timber.log.Timber
import javax.inject.Inject
/**
* Factory for creating [Network]
*
* @property excludedBlockchains excluded blockchains
*
[REDACTED_AUTHOR]
*/
class NetworkFactory @Inject constructor(
private val excludedBlockchains: ExcludedBlockchains,
) {
/**
* Create
*
* @param blockchain blockchain
* @param extraDerivationPath extra derivation path
* @param scanResponse scan response
*/
fun create(blockchain: Blockchain, extraDerivationPath: String?, scanResponse: ScanResponse): Network? {
return create(
blockchain = blockchain,
derivationPath = createDerivationPath(
blockchain = blockchain,
extraDerivationPath = extraDerivationPath,
cardDerivationStyleProvider = scanResponse.derivationStyleProvider,
),
canHandleTokens = scanResponse.card.canHandleToken(
blockchain = blockchain,
cardTypesResolver = scanResponse.cardTypesResolver,
excludedBlockchains = excludedBlockchains,
),
)
}
/**
* Create
*
* @param networkId network id
* @param derivationPath derivation path
* @param scanResponse scan response
*/
fun create(networkId: Network.ID, derivationPath: Network.DerivationPath, scanResponse: ScanResponse): Network? {
val blockchain = getBlockchain(networkId)
return create(
blockchain = blockchain,
derivationPath = derivationPath,
canHandleTokens = scanResponse.card.canHandleToken(
blockchain = blockchain,
cardTypesResolver = scanResponse.cardTypesResolver,
excludedBlockchains = excludedBlockchains,
),
)
}
/**
* Create
*
* @param blockchain blockchain
* @param extraDerivationPath extra derivation path
* @param derivationStyleProvider derivation style provider
* @param canHandleTokens flag that indicates whether the network can handle tokens
*/
fun create(
blockchain: Blockchain,
extraDerivationPath: String?,
derivationStyleProvider: DerivationStyleProvider?,
canHandleTokens: Boolean,
): Network? {
return create(
blockchain = blockchain,
derivationPath = createDerivationPath(
blockchain = blockchain,
extraDerivationPath = extraDerivationPath,
cardDerivationStyleProvider = derivationStyleProvider,
),
canHandleTokens = canHandleTokens,
)
}
private fun create(
blockchain: Blockchain,
derivationPath: Network.DerivationPath,
canHandleTokens: Boolean,
): Network? {
if (!blockchain.isBlockchainSupported()) return null
return runCatching {
Network(
id = Network.ID(value = blockchain.id, derivationPath = derivationPath),
backendId = blockchain.toNetworkId(),
name = blockchain.fullName,
isTestnet = blockchain.isTestnet(),
derivationPath = derivationPath,
currencySymbol = blockchain.currency,
standardType = getNetworkStandardType(blockchain),
hasFiatFeeRate = blockchain.feePaidCurrency() !is FeePaidCurrency.FeeResource,
canHandleTokens = canHandleTokens,
transactionExtrasType = blockchain.getSupportedTransactionExtras(),
)
}
.getOrNull()
}
private fun Blockchain.isBlockchainSupported(): Boolean {
if (this == Blockchain.Unknown) {
Timber.w("Unable to convert Unknown blockchain to the domain network model")
return false
}
if (this in excludedBlockchains) {
Timber.w("Unable to convert excluded blockchain to the domain network model")
return false
}
return true
}
private fun createDerivationPath(
blockchain: Blockchain,
extraDerivationPath: String?,
cardDerivationStyleProvider: DerivationStyleProvider?,
): Network.DerivationPath {
if (cardDerivationStyleProvider == null) return Network.DerivationPath.None
val defaultDerivationPath = getDefaultDerivationPath(blockchain, cardDerivationStyleProvider)
return if (extraDerivationPath.isNullOrBlank()) {
if (defaultDerivationPath.isNullOrBlank()) {
Network.DerivationPath.None
} else {
Network.DerivationPath.Card(defaultDerivationPath)
}
} else {
if (extraDerivationPath == defaultDerivationPath) {
Network.DerivationPath.Card(defaultDerivationPath)
} else {
Network.DerivationPath.Custom(extraDerivationPath)
}
}
}
private fun getDefaultDerivationPath(
blockchain: Blockchain,
derivationStyleProvider: DerivationStyleProvider,
): String? {
return blockchain.derivationPath(derivationStyleProvider.getDerivationStyle())?.rawPath
}
private fun getNetworkStandardType(blockchain: Blockchain): Network.StandardType {
return when (blockchain) {
Blockchain.Ethereum, Blockchain.EthereumTestnet -> Network.StandardType.ERC20
Blockchain.BSC, Blockchain.BSCTestnet -> Network.StandardType.BEP20
Blockchain.Binance, Blockchain.BinanceTestnet -> Network.StandardType.BEP2
Blockchain.Tron, Blockchain.TronTestnet -> Network.StandardType.TRC20
else -> Network.StandardType.Unspecified(blockchain.name)
}
}
@Suppress("LongMethod")
private fun Blockchain.getSupportedTransactionExtras(): Network.TransactionExtrasType {
return when (this) {
Blockchain.XRP -> Network.TransactionExtrasType.DESTINATION_TAG
Blockchain.Binance,
Blockchain.TON,
Blockchain.Cosmos,
Blockchain.TerraV1,
Blockchain.TerraV2,
Blockchain.Stellar,
Blockchain.Hedera,
Blockchain.Algorand,
Blockchain.Sei,
Blockchain.InternetComputer,
Blockchain.Casper,
-> Network.TransactionExtrasType.MEMO
// region Other blockchains
Blockchain.Unknown,
Blockchain.Alephium,
Blockchain.AlephiumTestnet,
Blockchain.Arbitrum,
Blockchain.ArbitrumTestnet,
Blockchain.Avalanche,
Blockchain.AvalancheTestnet,
Blockchain.BinanceTestnet,
Blockchain.BSC,
Blockchain.BSCTestnet,
Blockchain.Bitcoin,
Blockchain.BitcoinTestnet,
Blockchain.BitcoinCash,
Blockchain.BitcoinCashTestnet,
Blockchain.Cardano,
Blockchain.CosmosTestnet,
Blockchain.Dogecoin,
Blockchain.Ducatus,
Blockchain.Ethereum,
Blockchain.EthereumTestnet,
Blockchain.EthereumClassic,
Blockchain.EthereumClassicTestnet,
Blockchain.Fantom,
Blockchain.FantomTestnet,
Blockchain.Litecoin,
Blockchain.Near,
Blockchain.NearTestnet,
Blockchain.Polkadot,
Blockchain.PolkadotTestnet,
Blockchain.Kava,
Blockchain.KavaTestnet,
Blockchain.Kusama,
Blockchain.Polygon,
Blockchain.PolygonTestnet,
Blockchain.RSK,
Blockchain.SeiTestnet,
Blockchain.StellarTestnet,
Blockchain.Solana,
Blockchain.SolanaTestnet,
Blockchain.Tezos,
Blockchain.Tron,
Blockchain.TronTestnet,
Blockchain.Gnosis,
Blockchain.Dash,
Blockchain.Optimism,
Blockchain.OptimismTestnet,
Blockchain.Dischain,
Blockchain.EthereumPow,
Blockchain.EthereumPowTestnet,
Blockchain.Kaspa,
Blockchain.KaspaTestnet,
Blockchain.Telos,
Blockchain.TelosTestnet,
Blockchain.TONTestnet,
Blockchain.Ravencoin,
Blockchain.Clore,
Blockchain.RavencoinTestnet,
Blockchain.Cronos,
Blockchain.AlephZero,
Blockchain.AlephZeroTestnet,
Blockchain.OctaSpace,
Blockchain.OctaSpaceTestnet,
Blockchain.Chia,
Blockchain.ChiaTestnet,
Blockchain.Decimal,
Blockchain.DecimalTestnet,
Blockchain.XDC,
Blockchain.XDCTestnet,
Blockchain.VeChain,
Blockchain.VeChainTestnet,
Blockchain.Aptos,
Blockchain.AptosTestnet,
Blockchain.Playa3ull,
Blockchain.Shibarium,
Blockchain.ShibariumTestnet,
Blockchain.AlgorandTestnet,
Blockchain.HederaTestnet,
Blockchain.Aurora,
Blockchain.AuroraTestnet,
Blockchain.Areon,
Blockchain.AreonTestnet,
Blockchain.PulseChain,
Blockchain.PulseChainTestnet,
Blockchain.ZkSyncEra,
Blockchain.ZkSyncEraTestnet,
Blockchain.Nexa,
Blockchain.NexaTestnet,
Blockchain.Moonbeam,
Blockchain.MoonbeamTestnet,
Blockchain.Manta,
Blockchain.MantaTestnet,
Blockchain.PolygonZkEVM,
Blockchain.PolygonZkEVMTestnet,
Blockchain.Radiant,
Blockchain.Fact0rn,
Blockchain.Base,
Blockchain.BaseTestnet,
Blockchain.Moonriver,
Blockchain.MoonriverTestnet,
Blockchain.Mantle,
Blockchain.MantleTestnet,
Blockchain.Flare,
Blockchain.FlareTestnet,
Blockchain.Taraxa,
Blockchain.TaraxaTestnet,
Blockchain.Koinos,
Blockchain.KoinosTestnet,
Blockchain.Joystream,
Blockchain.Bittensor,
Blockchain.Filecoin,
Blockchain.Blast,
Blockchain.BlastTestnet,
Blockchain.Cyber,
Blockchain.CyberTestnet,
Blockchain.Sui,
Blockchain.SuiTestnet,
Blockchain.EnergyWebChain,
Blockchain.EnergyWebChainTestnet,
Blockchain.EnergyWebX,
Blockchain.EnergyWebXTestnet,
Blockchain.CasperTestnet,
Blockchain.Core,
Blockchain.CoreTestnet,
Blockchain.Xodex,
Blockchain.Canxium,
Blockchain.Chiliz,
Blockchain.ChilizTestnet,
Blockchain.VanarChain,
Blockchain.VanarChainTestnet,
Blockchain.OdysseyChain, Blockchain.OdysseyChainTestnet,
Blockchain.Bitrock, Blockchain.BitrockTestnet,
Blockchain.Sonic, Blockchain.SonicTestnet,
Blockchain.ApeChain, Blockchain.ApeChainTestnet,
Blockchain.Scroll, Blockchain.ScrollTestnet,
Blockchain.ZkLinkNova, Blockchain.ZkLinkNovaTestnet,
Blockchain.Pepecoin, Blockchain.PepecoinTestnet,
-> Network.TransactionExtrasType.NONE
// endregion
}
}
@VisibleForTesting(otherwise = VisibleForTesting.NONE)
fun createNetworkStandardType(blockchain: Blockchain) = getNetworkStandardType(blockchain)
@VisibleForTesting(otherwise = VisibleForTesting.NONE)
fun createSupportedTransactionExtras(blockchain: Blockchain) = blockchain.getSupportedTransactionExtras()
}

View file

@ -0,0 +1,468 @@
package com.tangem.data.common.network
import com.google.common.truth.Truth
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchainsdk.utils.ExcludedBlockchains
import com.tangem.common.test.domain.card.MockScanResponseFactory
import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory
import com.tangem.common.test.utils.ProvideTestModels
import com.tangem.domain.common.DerivationStyleProvider
import com.tangem.domain.common.configs.GenericCardConfig
import com.tangem.domain.common.configs.MultiWalletCardConfig
import com.tangem.domain.common.util.derivationStyleProvider
import com.tangem.domain.models.network.Network
import com.tangem.domain.models.scan.ScanResponse
import io.mockk.every
import io.mockk.mockk
import org.junit.jupiter.api.Nested
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
import org.junit.jupiter.params.ParameterizedTest
/**
[REDACTED_AUTHOR]
*/
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class NetworkFactoryTest {
private val networkFactory = NetworkFactory(excludedBlockchains = ExcludedBlockchains())
@Nested
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
inner class Create {
@Test
fun `create if blockchain is excluded`() {
// Arrange
val excludedBlockchains = mockk<ExcludedBlockchains>()
val networkFactory = NetworkFactory(excludedBlockchains = excludedBlockchains)
every { any() in excludedBlockchains } returns true
// Act
val actual = networkFactory.create(
blockchain = Blockchain.Ethereum,
extraDerivationPath = null,
scanResponse = createMultiWalletScanResponse(),
)
// Assert
Truth.assertThat(actual).isNull()
}
@ParameterizedTest
@ProvideTestModels
fun create(model: CreateTestModel) {
// Act
val actual = when (model) {
is CreateTestModel.First -> {
networkFactory.create(
blockchain = model.blockchain,
extraDerivationPath = model.extraDerivationPath,
scanResponse = model.scanResponse,
)
}
is CreateTestModel.Second -> {
networkFactory.create(
networkId = model.networkId,
derivationPath = model.derivationPath,
scanResponse = model.scanResponse,
)
}
is CreateTestModel.Third -> {
networkFactory.create(
blockchain = model.blockchain,
extraDerivationPath = model.extraDerivationPath,
derivationStyleProvider = model.derivationStyleProvider,
canHandleTokens = model.canHandleTokens,
)
}
}
// Assert
Truth.assertThat(actual).isEqualTo(model.expected)
}
@Suppress("unused")
private fun provideTestModels() = listOf(
// region create(blockchain: Blockchain, extraDerivationPath: String?, scanResponse: ScanResponse)
CreateTestModel.First(
blockchain = Blockchain.Unknown,
extraDerivationPath = null, // never-mind
scanResponse = createMultiWalletScanResponse(), // never-mind
expected = null,
),
createFirst(
extraDerivationPath = null,
scanResponse = createGenericScanResponse(), // default derivation path is null
expectedDerivationPath = Network.DerivationPath.None,
),
createFirst(
extraDerivationPath = null,
scanResponse = createMultiWalletScanResponse(),
expectedDerivationPath = Network.DerivationPath.Card(value = "m/44'/60'/0'/0/0"), // use default
),
createFirst(
extraDerivationPath = "m/44'/60'/0'/0/0", // as default
scanResponse = createMultiWalletScanResponse(),
expectedDerivationPath = Network.DerivationPath.Card(value = "m/44'/60'/0'/0/0"),
),
createFirst(
extraDerivationPath = "m/84'/0'/0'/0/0",
scanResponse = createMultiWalletScanResponse(),
expectedDerivationPath = Network.DerivationPath.Custom(value = "m/84'/0'/0'/0/0"),
),
// endregion
// region create(networkId: Network.ID, derivationPath: Network.DerivationPath, scanResponse: ScanResponse)
CreateTestModel.Second(
networkId = Network.ID(value = "1", derivationPath = Network.DerivationPath.None),
derivationPath = Network.DerivationPath.None, // never-mind
scanResponse = createMultiWalletScanResponse(), // never-mind
expected = null,
),
createSecond(
scanResponse = createGenericScanResponse(), // default derivation path is null
derivationPath = Network.DerivationPath.None,
),
createSecond(
scanResponse = createMultiWalletScanResponse(),
derivationPath = Network.DerivationPath.None,
),
createSecond(
scanResponse = createMultiWalletScanResponse(),
derivationPath = Network.DerivationPath.Card(value = "m/44'/60'/0'/0/0"),
),
createSecond(
scanResponse = createMultiWalletScanResponse(),
derivationPath = Network.DerivationPath.Custom(value = "m/84'/0'/0'/0/0"),
),
// endregion
// region fun create(blockchain: Blockchain, extraDerivationPath: String?, derivationStyleProvider: DerivationStyleProvider?, canHandleTokens: Boolean)
CreateTestModel.Third(
blockchain = Blockchain.Unknown,
extraDerivationPath = null, // never-mind
derivationStyleProvider = createMultiWalletScanResponse().derivationStyleProvider, // never-mind
canHandleTokens = true, // never-mind
expected = null,
),
createThird(
extraDerivationPath = null,
derivationStyleProvider = createGenericScanResponse().derivationStyleProvider, // default derivation path is null
canHandleTokens = true,
expectedDerivationPath = Network.DerivationPath.None,
),
createThird(
extraDerivationPath = null,
derivationStyleProvider = createMultiWalletScanResponse().derivationStyleProvider,
canHandleTokens = true,
expectedDerivationPath = Network.DerivationPath.Card(value = "m/44'/60'/0'/0/0"), // use default
),
createThird(
extraDerivationPath = "m/44'/60'/0'/0/0", // as default
derivationStyleProvider = createMultiWalletScanResponse().derivationStyleProvider,
canHandleTokens = false,
expectedDerivationPath = Network.DerivationPath.Card(value = "m/44'/60'/0'/0/0"),
),
createThird(
extraDerivationPath = "m/84'/0'/0'/0/0",
derivationStyleProvider = createMultiWalletScanResponse().derivationStyleProvider,
canHandleTokens = false,
expectedDerivationPath = Network.DerivationPath.Custom(value = "m/84'/0'/0'/0/0"),
),
// endregion
)
private fun createFirst(
extraDerivationPath: String?,
scanResponse: ScanResponse,
expectedDerivationPath: Network.DerivationPath,
): CreateTestModel.First {
return CreateTestModel.First(
blockchain = Blockchain.Ethereum,
extraDerivationPath = extraDerivationPath,
scanResponse = scanResponse,
expected = MockCryptoCurrencyFactory().ethereum.network.copy(
id = Network.ID(
value = Blockchain.Ethereum.id,
derivationPath = expectedDerivationPath,
),
derivationPath = expectedDerivationPath,
canHandleTokens = true,
),
)
}
private fun createSecond(
scanResponse: ScanResponse,
derivationPath: Network.DerivationPath,
): CreateTestModel.Second {
return CreateTestModel.Second(
networkId = Network.ID(value = Blockchain.Ethereum.id, derivationPath = derivationPath),
derivationPath = derivationPath,
scanResponse = scanResponse,
expected = MockCryptoCurrencyFactory().ethereum.network.copy(
id = Network.ID(
value = Blockchain.Ethereum.id,
derivationPath = derivationPath,
),
derivationPath = derivationPath,
canHandleTokens = true,
),
)
}
private fun createThird(
extraDerivationPath: String?,
derivationStyleProvider: DerivationStyleProvider?,
canHandleTokens: Boolean,
expectedDerivationPath: Network.DerivationPath,
): CreateTestModel.Third {
return CreateTestModel.Third(
blockchain = Blockchain.Ethereum,
extraDerivationPath = extraDerivationPath,
derivationStyleProvider = derivationStyleProvider,
canHandleTokens = canHandleTokens,
expected = MockCryptoCurrencyFactory().ethereum.network.copy(
id = Network.ID(value = Blockchain.Ethereum.id, derivationPath = expectedDerivationPath),
derivationPath = expectedDerivationPath,
canHandleTokens = canHandleTokens,
),
)
}
private fun createMultiWalletScanResponse(): ScanResponse {
return MockScanResponseFactory.create(
cardConfig = MultiWalletCardConfig,
derivedKeys = emptyMap(),
)
}
private fun createGenericScanResponse(): ScanResponse {
return MockScanResponseFactory.create(
cardConfig = GenericCardConfig(maxWalletCount = 1),
derivedKeys = emptyMap(),
)
}
}
sealed interface CreateTestModel {
val expected: Network?
data class First(
val blockchain: Blockchain,
val extraDerivationPath: String?,
val scanResponse: ScanResponse,
override val expected: Network?,
) : CreateTestModel
data class Second(
val networkId: Network.ID,
val derivationPath: Network.DerivationPath,
val scanResponse: ScanResponse,
override val expected: Network?,
) : CreateTestModel
data class Third(
val blockchain: Blockchain,
val extraDerivationPath: String?,
val derivationStyleProvider: DerivationStyleProvider?,
val canHandleTokens: Boolean,
override val expected: Network?,
) : CreateTestModel
}
@Nested
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
inner class GetNetworkStandardType {
@ParameterizedTest
@ProvideTestModels
fun getNetworkStandardType(model: GetNetworkStandardTypeModel) {
// Act
val actual = model.blockchains.map(networkFactory::createNetworkStandardType)
// Assert
val expected = model.blockchains.map(model.expected)
Truth.assertThat(actual).isEqualTo(expected)
}
@Suppress("unused")
private fun provideTestModels() = listOf(
GetNetworkStandardTypeModel(
blockchains = listOf(Blockchain.Ethereum, Blockchain.EthereumTestnet),
expected = { Network.StandardType.ERC20 },
),
GetNetworkStandardTypeModel(
blockchains = listOf(Blockchain.BSC, Blockchain.BSCTestnet),
expected = { Network.StandardType.BEP20 },
),
GetNetworkStandardTypeModel(
blockchains = listOf(Blockchain.Binance, Blockchain.BinanceTestnet),
expected = { Network.StandardType.BEP2 },
),
GetNetworkStandardTypeModel(
blockchains = listOf(Blockchain.Tron, Blockchain.TronTestnet),
expected = { Network.StandardType.TRC20 },
),
GetNetworkStandardTypeModel(
blockchains = Blockchain.entries - listOf(
Blockchain.Ethereum,
Blockchain.EthereumTestnet,
Blockchain.BSC,
Blockchain.BSCTestnet,
Blockchain.Binance,
Blockchain.BinanceTestnet,
Blockchain.Tron,
Blockchain.TronTestnet,
),
expected = { Network.StandardType.Unspecified(it.name) },
),
)
}
data class GetNetworkStandardTypeModel(
val blockchains: List<Blockchain>,
val expected: (Blockchain) -> Network.StandardType,
)
@Nested
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
inner class GetSupportedTransactionExtras {
@ParameterizedTest
@ProvideTestModels
fun getSupportedTransactionExtras(model: GetSupportedTransactionExtrasModel) {
// Act
val actual = model.blockchains.map(networkFactory::createSupportedTransactionExtras)
// Assert
val expected = List(size = model.blockchains.size) { model.expected }
Truth.assertThat(actual).isEqualTo(expected)
}
@Suppress("unused")
private fun provideTestModels() = listOf(
GetSupportedTransactionExtrasModel(
blockchains = listOf(Blockchain.XRP),
expected = Network.TransactionExtrasType.DESTINATION_TAG,
),
GetSupportedTransactionExtrasModel(
blockchains = listOf(
Blockchain.Binance,
Blockchain.TON,
Blockchain.Cosmos,
Blockchain.TerraV1,
Blockchain.TerraV2,
Blockchain.Stellar,
Blockchain.Hedera,
Blockchain.Algorand,
Blockchain.Sei,
Blockchain.InternetComputer,
Blockchain.Casper,
),
expected = Network.TransactionExtrasType.MEMO,
),
GetSupportedTransactionExtrasModel(
blockchains = listOf(
Blockchain.Unknown,
Blockchain.Alephium, Blockchain.AlephiumTestnet,
Blockchain.Arbitrum, Blockchain.ArbitrumTestnet,
Blockchain.Avalanche, Blockchain.AvalancheTestnet,
Blockchain.BinanceTestnet,
Blockchain.BSC, Blockchain.BSCTestnet,
Blockchain.Bitcoin, Blockchain.BitcoinTestnet,
Blockchain.BitcoinCash, Blockchain.BitcoinCashTestnet,
Blockchain.Cardano,
Blockchain.CosmosTestnet,
Blockchain.Dogecoin,
Blockchain.Ducatus,
Blockchain.Ethereum, Blockchain.EthereumTestnet,
Blockchain.EthereumClassic, Blockchain.EthereumClassicTestnet,
Blockchain.Fantom, Blockchain.FantomTestnet,
Blockchain.Litecoin,
Blockchain.Near, Blockchain.NearTestnet,
Blockchain.Polkadot, Blockchain.PolkadotTestnet,
Blockchain.Kava, Blockchain.KavaTestnet,
Blockchain.Kusama,
Blockchain.Polygon, Blockchain.PolygonTestnet,
Blockchain.RSK,
Blockchain.SeiTestnet,
Blockchain.StellarTestnet,
Blockchain.Solana, Blockchain.SolanaTestnet,
Blockchain.Tezos,
Blockchain.Tron, Blockchain.TronTestnet,
Blockchain.Gnosis,
Blockchain.Dash,
Blockchain.Optimism, Blockchain.OptimismTestnet,
Blockchain.Dischain,
Blockchain.EthereumPow, Blockchain.EthereumPowTestnet,
Blockchain.Kaspa, Blockchain.KaspaTestnet,
Blockchain.Telos, Blockchain.TelosTestnet,
Blockchain.TONTestnet,
Blockchain.Ravencoin,
Blockchain.Clore,
Blockchain.RavencoinTestnet,
Blockchain.Cronos,
Blockchain.AlephZero, Blockchain.AlephZeroTestnet,
Blockchain.OctaSpace, Blockchain.OctaSpaceTestnet,
Blockchain.Chia, Blockchain.ChiaTestnet,
Blockchain.Decimal, Blockchain.DecimalTestnet,
Blockchain.XDC, Blockchain.XDCTestnet,
Blockchain.VeChain, Blockchain.VeChainTestnet,
Blockchain.Aptos, Blockchain.AptosTestnet,
Blockchain.Playa3ull,
Blockchain.Shibarium, Blockchain.ShibariumTestnet,
Blockchain.AlgorandTestnet,
Blockchain.HederaTestnet,
Blockchain.Aurora, Blockchain.AuroraTestnet,
Blockchain.Areon, Blockchain.AreonTestnet,
Blockchain.PulseChain, Blockchain.PulseChainTestnet,
Blockchain.ZkSyncEra, Blockchain.ZkSyncEraTestnet,
Blockchain.Nexa, Blockchain.NexaTestnet,
Blockchain.Moonbeam, Blockchain.MoonbeamTestnet,
Blockchain.Manta, Blockchain.MantaTestnet,
Blockchain.PolygonZkEVM, Blockchain.PolygonZkEVMTestnet,
Blockchain.Radiant,
Blockchain.Fact0rn,
Blockchain.Base, Blockchain.BaseTestnet,
Blockchain.Moonriver, Blockchain.MoonriverTestnet,
Blockchain.Mantle, Blockchain.MantleTestnet,
Blockchain.Flare, Blockchain.FlareTestnet,
Blockchain.Taraxa, Blockchain.TaraxaTestnet,
Blockchain.Koinos, Blockchain.KoinosTestnet,
Blockchain.Joystream,
Blockchain.Bittensor,
Blockchain.Filecoin,
Blockchain.Blast, Blockchain.BlastTestnet,
Blockchain.Cyber, Blockchain.CyberTestnet,
Blockchain.Sui, Blockchain.SuiTestnet,
Blockchain.EnergyWebChain, Blockchain.EnergyWebChainTestnet,
Blockchain.EnergyWebX, Blockchain.EnergyWebXTestnet,
Blockchain.CasperTestnet,
Blockchain.Core, Blockchain.CoreTestnet,
Blockchain.Xodex,
Blockchain.Canxium,
Blockchain.Chiliz, Blockchain.ChilizTestnet,
Blockchain.VanarChain, Blockchain.VanarChainTestnet,
Blockchain.OdysseyChain, Blockchain.OdysseyChainTestnet,
Blockchain.Bitrock, Blockchain.BitrockTestnet,
Blockchain.Sonic, Blockchain.SonicTestnet,
Blockchain.ApeChain, Blockchain.ApeChainTestnet,
Blockchain.Scroll, Blockchain.ScrollTestnet,
Blockchain.ZkLinkNova, Blockchain.ZkLinkNovaTestnet,
Blockchain.Pepecoin, Blockchain.PepecoinTestnet,
),
expected = Network.TransactionExtrasType.NONE,
),
)
}
data class GetSupportedTransactionExtrasModel(
val blockchains: List<Blockchain>,
val expected: Network.TransactionExtrasType,
)
}