Updated on 2026-08-14

This commit is contained in:
Tangem 2025-05-20 15:13:47 +04:00
parent 33b7a53905
commit c5560c3c6a
101 changed files with 274 additions and 272 deletions

View file

@ -84,7 +84,7 @@ class CryptoCurrencyFactory(
}
fun createCoin(network: Network): CryptoCurrency.Coin {
val blockchain = Blockchain.fromId(network.id.value)
val blockchain = Blockchain.fromId(network.rawId)
return CryptoCurrency.Coin(
id = getCoinId(network, blockchain.toCoinId()),

View file

@ -13,7 +13,7 @@ import com.tangem.domain.models.scan.ScanResponse
import timber.log.Timber
fun getBlockchain(networkId: Network.ID): Blockchain {
return Blockchain.fromId(networkId.value)
return Blockchain.fromId(networkId.rawId.value)
}
fun getNetwork(
@ -27,16 +27,18 @@ fun getNetwork(
return null
}
val derivationPath = getNetworkDerivationPath(
blockchain = blockchain,
extraDerivationPath = extraDerivationPath,
cardDerivationStyleProvider = derivationStyleProvider,
)
return Network(
id = Network.ID(blockchain.id),
id = Network.ID(value = blockchain.id, derivationPath = derivationPath),
backendId = blockchain.toNetworkId(),
name = blockchain.fullName,
isTestnet = blockchain.isTestnet(),
derivationPath = getNetworkDerivationPath(
blockchain = blockchain,
extraDerivationPath = extraDerivationPath,
cardDerivationStyleProvider = derivationStyleProvider,
),
derivationPath = derivationPath,
currencySymbol = blockchain.currency,
standardType = getNetworkStandardType(blockchain),
hasFiatFeeRate = blockchain.feePaidCurrency() !is FeePaidCurrency.FeeResource,

View file

@ -78,12 +78,12 @@ fun List<UserTokensResponse.Token>.hasCoinForToken(network: Network): Boolean {
private fun getCurrencyIdBody(network: Network): CurrencyIdBody {
return when (val path = network.derivationPath) {
is Network.DerivationPath.Custom -> CurrencyIdBody.NetworkIdWithDerivationPath(
rawId = network.id.value,
rawId = network.rawId,
derivationPath = path.value,
)
is Network.DerivationPath.Card,
is Network.DerivationPath.None,
-> CurrencyIdBody.NetworkId(network.id.value)
-> CurrencyIdBody.NetworkId(network.rawId)
}
}

View file

@ -48,7 +48,7 @@ internal class DefaultCustomTokensRepository(
override suspend fun validateContractAddress(contractAddress: String, networkId: Network.ID): Boolean =
withContext(dispatchers.io) {
when (val blockchain = Blockchain.fromId(networkId.value)) {
when (val blockchain = Blockchain.fromId(networkId.rawId.value)) {
Blockchain.Unknown,
Blockchain.Binance,
Blockchain.BinanceTestnet,
@ -76,7 +76,7 @@ internal class DefaultCustomTokensRepository(
}
storedCurrencies.tokens.none { token ->
Blockchain.fromId(networkId.value).toNetworkId() == token.networkId &&
Blockchain.fromId(networkId.rawId.value).toNetworkId() == token.networkId &&
derivationPath.value == token.derivationPath &&
contractAddress.equals(token.contractAddress, ignoreCase = true)
}

View file

@ -20,7 +20,7 @@ internal object NetworkStatusSupplierModule {
return object : SingleNetworkStatusSupplier(
factory = factory,
keyCreator = {
"single_network_status_${it.userWalletId.stringValue}_${it.network.id.value}_" +
"single_network_status_${it.userWalletId.stringValue}_${it.network.rawId}_" +
it.network.derivationPath.value
},
) {}

View file

@ -62,7 +62,7 @@ internal class CommonNetworkStatusFetcher @Inject constructor(
networksStatusesStore.storeStatus(userWalletId = userWalletId, status = status)
}
.onLeft {
Timber.e("Failed to fetch network status for $userWalletId [${network.id.value}]: $it")
Timber.e("Failed to fetch network status for $userWalletId [${network.rawId}]: $it")
networksStatusesStore.setSourceAsOnlyCache(userWalletId = userWalletId, network = network)
}
}

View file

@ -533,7 +533,7 @@ internal class DefaultNFTRepository @Inject constructor(
private fun Pair<UserWalletId, Network>.formatted(): String {
val (walletId, network) = this
return walletId.stringValue + "_" + network.id.value + "_" + network.derivationPath.value
return walletId.stringValue + "_" + network.rawId + "_" + network.derivationPath.value
}
private fun Network.canHandleNFTs(): Boolean {

View file

@ -19,7 +19,7 @@ internal class MercuryoTopUpRepository @Inject constructor(
override suspend fun getTopUpUrl(cryptoCurrency: CryptoCurrency, walletAddress: String): String =
withContext(dispatchersProvider.default) {
val blockchain = Blockchain.fromId(cryptoCurrency.network.id.value)
val blockchain = Blockchain.fromId(cryptoCurrency.network.rawId)
val environmentConfig = environmentConfigStorage.getConfigSync()
val builder = Uri.Builder()

View file

@ -7,7 +7,10 @@ import com.tangem.domain.qrscanning.models.SourceType
import com.tangem.domain.qrscanning.repository.QrScanningEventsRepository
import com.tangem.domain.tokens.model.CryptoCurrency
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.yield
import java.math.BigDecimal
import java.net.URLDecoder
@ -87,7 +90,7 @@ internal class DefaultQrScanningEventsRepository : QrScanningEventsRepository {
}
private fun stripSchema(raw: String, currency: CryptoCurrency): String {
val qrSchemas = Blockchain.fromId(currency.network.id.value).getShareScheme()
val qrSchemas = Blockchain.fromId(currency.network.rawId).getShareScheme()
// The most specific (i.e. the most lengthy) prefixes always come first
qrSchemas

View file

@ -76,7 +76,7 @@ internal class DefaultQrScanningEventsRepositoryTest {
@Test
fun testBip021() {
every { network.id } returns Network.ID(Blockchain.Bitcoin.id)
every { network.rawId } returns Blockchain.Bitcoin.id
positiveCase(
"$schema1:$address1",
QrResult(address = address1),
@ -126,7 +126,7 @@ internal class DefaultQrScanningEventsRepositoryTest {
@Test
fun testErc681Coin() {
every { network.id } returns Network.ID(Blockchain.Ethereum.id)
every { network.rawId } returns Blockchain.Ethereum.id
positiveCase(
address2,
QrResult(address = address2),
@ -181,7 +181,7 @@ internal class DefaultQrScanningEventsRepositoryTest {
@Test
fun testErc681Token() {
every { network.id } returns Network.ID(Blockchain.Ethereum.id)
every { network.rawId } returns Blockchain.Ethereum.id
positiveCase(
address2,
QrResult(address = address2),

View file

@ -245,7 +245,7 @@ internal class DefaultStakingRepository(
}
private fun checkFeatureToggleEnabled(networkId: Network.ID): Boolean {
return when (Blockchain.fromId(networkId.value)) {
return when (Blockchain.fromId(networkId.rawId.value)) {
Blockchain.TON -> stakingFeatureToggles.isTonStakingEnabled
Blockchain.Cardano -> stakingFeatureToggles.isCardanoStakingEnabled
else -> true
@ -256,7 +256,7 @@ internal class DefaultStakingRepository(
val userWallet = getUserWalletUseCase(userWalletId).getOrElse {
error("Failed to get user wallet")
}
val blockchainId = cryptoCurrency.network.id.value
val blockchainId = cryptoCurrency.network.rawId
return when {
isSolana(blockchainId) -> INVALID_BATCHES_FOR_SOLANA.contains(userWallet.scanResponse.card.batchId)
isCardano(blockchainId) -> !userWallet.scanResponse.card.isWallet2

View file

@ -39,7 +39,7 @@ internal object YieldBalanceSupplierModule {
return object : SingleYieldBalanceSupplier(
factory = factory,
keyCreator = {
"single_yield_balance_${it.userWalletId.stringValue}_${it.network.id.value}_" +
"single_yield_balance_${it.userWalletId.stringValue}_${it.network.rawId}_" +
it.network.derivationPath.value
},
) {}

View file

@ -354,7 +354,7 @@ internal class DefaultCurrenciesRepository(
"Unable to find tokens response for user wallet with provided ID: $userWalletId"
},
)
val blockchain = Blockchain.fromId(networkId.value)
val blockchain = Blockchain.fromId(networkId.rawId.value)
val blockchainNetworkId = blockchain.toNetworkId()
val coinId = blockchain.toCoinId()
@ -407,7 +407,7 @@ internal class DefaultCurrenciesRepository(
cryptoCurrencyStatus: CryptoCurrencyStatus,
coinStatus: CryptoCurrencyStatus?,
): Boolean {
val blockchain = Blockchain.fromId(cryptoCurrencyStatus.currency.network.id.value)
val blockchain = Blockchain.fromId(cryptoCurrencyStatus.currency.network.rawId)
val isBitcoinBlockchain = blockchain == Blockchain.Bitcoin || blockchain == Blockchain.BitcoinTestnet
return when {
cryptoCurrencyStatus.currency is CryptoCurrency.Coin && isBitcoinBlockchain -> {
@ -422,7 +422,7 @@ internal class DefaultCurrenciesRepository(
override suspend fun getFeePaidCurrency(userWalletId: UserWalletId, network: Network): FeePaidCurrency {
return withContext(dispatchers.io) {
val blockchain = Blockchain.fromId(network.id.value)
val blockchain = Blockchain.fromId(network.rawId)
when (val feePaidCurrency = blockchain.feePaidCurrency()) {
FeePaidSdkCurrency.Coin -> FeePaidCurrency.Coin
FeePaidSdkCurrency.SameCurrency -> FeePaidCurrency.SameCurrency

View file

@ -136,7 +136,7 @@ internal class DefaultCurrencyChecksRepository(
val balanceValue = currencyStatus.value as? CryptoCurrencyStatus.Loaded ?: return null
val stakingBalance = balanceValue.yieldBalance as? YieldBalance.Data
val stakingTotalBalance = stakingBalance?.getTotalStakingBalance(
blockchainId = currencyStatus.currency.network.id.value,
blockchainId = currencyStatus.currency.network.rawId,
).orZero()
return when {
balanceValue.amount.isZero() && stakingTotalBalance.isZero() -> null

View file

@ -39,7 +39,7 @@ internal class DefaultPolkadotAccountHealthCheckRepository(
override suspend fun runCheck(userWalletId: UserWalletId, network: Network) {
// Run Polkadot account health check
if (Blockchain.fromId(network.id.value) != Blockchain.Polkadot) return
if (Blockchain.fromId(network.rawId) != Blockchain.Polkadot) return
val walletManager = walletManagersFacade.getOrCreateWalletManager(userWalletId, network)
val address = requireNotNull(walletManager?.wallet?.address) {

View file

@ -7,7 +7,7 @@ import com.tangem.domain.transaction.FeeRepository
internal class DefaultFeeRepository : FeeRepository {
override fun isFeeApproximate(networkId: Network.ID, amountType: AmountType): Boolean {
val blockchain = Blockchain.fromId(networkId.value)
val blockchain = Blockchain.fromId(networkId.rawId.value)
return blockchain.isFeeApproximate(amountType)
}
}

View file

@ -47,14 +47,14 @@ internal class DefaultTransactionRepository(
network: Network,
txExtras: TransactionExtras?,
): TransactionData.Uncompiled = withContext(coroutineDispatcherProvider.io) {
val blockchain = Blockchain.fromId(network.id.value)
val blockchain = Blockchain.fromId(network.rawId)
val walletManager = walletManagersFacade.getOrCreateWalletManager(
userWalletId = userWalletId,
blockchain = blockchain,
derivationPath = network.derivationPath.value,
) ?: error("Wallet manager not found")
val extras = txExtras ?: getMemoExtras(networkId = network.id.value, memo)
val extras = txExtras ?: getMemoExtras(networkId = network.rawId, memo)
return@withContext if (fee != null) {
walletManager.createTransaction(
@ -83,7 +83,7 @@ internal class DefaultTransactionRepository(
userWalletId: UserWalletId,
network: Network,
): TransactionData.Uncompiled = withContext(coroutineDispatcherProvider.io) {
val blockchain = Blockchain.fromId(network.id.value)
val blockchain = Blockchain.fromId(network.rawId)
val walletManager = walletManagersFacade.getOrCreateWalletManager(
userWalletId = userWalletId,
blockchain = blockchain,
@ -115,14 +115,14 @@ internal class DefaultTransactionRepository(
destination = destination,
userWalletId = userWalletId,
network = network,
txExtras = getMemoExtras(networkId = network.id.value, memo = memo) ?: extras,
txExtras = getMemoExtras(networkId = network.rawId, memo = memo) ?: extras,
)
} else {
TransactionData.Uncompiled(
amount = amount,
sourceAddress = walletManager.wallet.address,
destinationAddress = destination,
extras = getMemoExtras(networkId = network.id.value, memo = memo) ?: extras,
extras = getMemoExtras(networkId = network.rawId, memo = memo) ?: extras,
fee = null,
)
}
@ -137,7 +137,7 @@ internal class DefaultTransactionRepository(
userWalletId: UserWalletId,
network: Network,
): TransactionData.Uncompiled = withContext(coroutineDispatcherProvider.io) {
val blockchain = Blockchain.fromId(network.id.value)
val blockchain = Blockchain.fromId(network.rawId)
val extras = createTransactionDataExtras(
callData = SmartContractCallDataProviderFactory.getApprovalCallData(
@ -170,7 +170,7 @@ internal class DefaultTransactionRepository(
userWalletId: UserWalletId,
network: Network,
): TransactionData.Uncompiled = withContext(coroutineDispatcherProvider.io) {
val blockchain = Blockchain.fromId(network.id.value)
val blockchain = Blockchain.fromId(network.rawId)
// For now transfer one nft asset at a time
val updatedNFTAsset = nftAsset.copy(
@ -228,7 +228,7 @@ internal class DefaultTransactionRepository(
userWalletId: UserWalletId,
network: Network,
): Result<Unit> = withContext(coroutineDispatcherProvider.io) {
val blockchain = Blockchain.fromId(network.id.value)
val blockchain = Blockchain.fromId(network.rawId)
val walletManager = walletManagersStore.getSyncOrNull(
userWalletId = userWalletId,
blockchain = blockchain,
@ -243,7 +243,7 @@ internal class DefaultTransactionRepository(
fee = fee ?: Fee.Common(amount = amount),
destination = destination,
).copy(
extras = getMemoExtras(networkId = network.id.value, memo = memo),
extras = getMemoExtras(networkId = network.rawId, memo = memo),
)
validator.validate(transactionData = transactionData)
@ -259,7 +259,7 @@ internal class DefaultTransactionRepository(
userWalletId: UserWalletId,
network: Network,
) = withContext(coroutineDispatcherProvider.io) {
val blockchain = Blockchain.fromId(network.id.value)
val blockchain = Blockchain.fromId(network.rawId)
val walletManager = walletManagersFacade.getOrCreateWalletManager(
userWalletId = userWalletId,
blockchain = blockchain,
@ -275,7 +275,7 @@ internal class DefaultTransactionRepository(
network: Network,
mode: TransactionSender.MultipleTransactionSendMode,
) = withContext(coroutineDispatcherProvider.io) {
val blockchain = Blockchain.fromId(network.id.value)
val blockchain = Blockchain.fromId(network.rawId)
val walletManager = walletManagersFacade.getOrCreateWalletManager(
userWalletId = userWalletId,
blockchain = blockchain,
@ -315,7 +315,7 @@ internal class DefaultTransactionRepository(
spenderAddress: String,
): BigDecimal {
val walletManager = walletManagersFacade.getOrCreateWalletManager(userWalletId, cryptoCurrency.network)
val blockchain = Blockchain.fromId(cryptoCurrency.network.id.value)
val blockchain = Blockchain.fromId(cryptoCurrency.network.rawId)
val allowanceResult = (walletManager as? Approver)?.getAllowance(
spenderAddress,
Token(
@ -388,7 +388,7 @@ internal class DefaultTransactionRepository(
}
private suspend fun getPreparer(network: Network, userWalletId: UserWalletId): TransactionPreparer {
val blockchain = Blockchain.fromId(network.id.value)
val blockchain = Blockchain.fromId(network.rawId)
val walletManager = walletManagersFacade.getOrCreateWalletManager(
userWalletId = userWalletId,
blockchain = blockchain,

View file

@ -21,7 +21,7 @@ class DefaultWalletAddressServiceRepository(
override suspend fun validateAddress(userWalletId: UserWalletId, network: Network, address: String): Boolean =
withContext(dispatchers.io) {
val blockchain = Blockchain.fromId(network.id.value)
val blockchain = Blockchain.fromId(network.rawId)
if (blockchain.isNear()) {
val walletManager = walletManagersFacade.getOrCreateWalletManager(
@ -37,7 +37,7 @@ class DefaultWalletAddressServiceRepository(
override fun validateMemo(network: Network, memo: String): Boolean {
if (memo.isEmpty()) return true
return when (network.id.value) {
return when (network.rawId) {
Blockchain.XRP.id -> {
val tag = memo.toLongOrNull()
tag != null && tag <= XRP_TAG_MAX_NUMBER
@ -50,7 +50,7 @@ class DefaultWalletAddressServiceRepository(
}
override suspend fun parseSharedAddress(input: String, network: Network): ParsedQrCode {
val blockchain = Blockchain.fromId(network.id.value)
val blockchain = Blockchain.fromId(network.rawId)
val addressSchemeSplit = when (blockchain) {
Blockchain.BitcoinCash, Blockchain.Kaspa -> listOf(input)
else -> input.split(":")

View file

@ -77,7 +77,7 @@ class DefaultTxHistoryRepository(
@Deprecated("Replace with getTxExploreUrl [UserWalletId, Network] instead")
override fun getTxExploreUrl(txHash: String, networkId: Network.ID): String {
val blockchain = Blockchain.fromId(networkId.value)
val blockchain = Blockchain.fromId(networkId.rawId.value)
return when (val txExploreState = blockchain.getExploreTxUrl(txHash)) {
is TxExploreState.Url -> txExploreState.url
is TxExploreState.Unsupported -> ""
@ -85,7 +85,7 @@ class DefaultTxHistoryRepository(
}
override suspend fun getTxExploreUrl(userWalletId: UserWalletId, network: Network): String {
val blockchain = Blockchain.fromId(network.id.value)
val blockchain = Blockchain.fromId(network.rawId)
val walletManager = walletManagersFacade.getOrCreateWalletManager(
userWalletId = userWalletId,
network = network,

View file

@ -9,12 +9,8 @@ import com.tangem.data.walletconnect.request.WcRequestToUseCaseConverter
import com.tangem.data.walletconnect.request.WcRequestToUseCaseConverter.Companion.fromJson
import com.tangem.data.walletconnect.sign.WcMethodUseCaseContext
import com.tangem.data.walletconnect.utils.WcNamespaceConverter
import com.tangem.domain.walletconnect.model.WcEthAddChain
import com.tangem.domain.models.network.Network
import com.tangem.domain.walletconnect.model.WcEthMethod
import com.tangem.domain.walletconnect.model.WcEthMethodName
import com.tangem.domain.walletconnect.model.WcEthSignTypedDataParams
import com.tangem.domain.walletconnect.model.WcEthTransactionParams
import com.tangem.domain.walletconnect.model.*
import com.tangem.domain.walletconnect.model.sdkcopy.WcSdkSessionRequest
import com.tangem.domain.walletconnect.repository.WcSessionsManager
import com.tangem.domain.walletconnect.usecase.method.WcMethodUseCase
@ -129,7 +125,7 @@ internal class WcEthNetwork(
}
override fun toCAIP2(network: Network): CAIP2? {
val blockchain = Blockchain.fromId(network.id.value)
val blockchain = Blockchain.fromId(network.rawId)
if (!blockchain.isEvm()) return null
val chainId = blockchain.getChainId() ?: return null
return CAIP2(

View file

@ -20,7 +20,7 @@ internal object WcEthTxHelper {
val gasLimit = txParams.gas?.hexToBigDecimal() ?: return null
val gasPrice = txParams.gasPrice?.hexToBigDecimal() ?: return null
val blockchain = Blockchain.fromId(network.id.value)
val blockchain = Blockchain.fromId(network.rawId)
var feeDecimal = (gasLimit * gasPrice)
.movePointLeft(blockchain.decimals())
@ -38,7 +38,7 @@ internal object WcEthTxHelper {
txParams: WcEthTransactionParams,
): TransactionData.Uncompiled? {
val destinationAddress = txParams.to ?: return null
val blockchain = Blockchain.fromId(network.id.value)
val blockchain = Blockchain.fromId(network.rawId)
val value = (txParams.value ?: "0")
.hexToBigDecimal()
.movePointLeft(blockchain.decimals())

View file

@ -57,7 +57,7 @@ internal class WcSolanaNetwork(
private suspend fun getAccountAddress(network: Network): String? {
return try {
walletManager.getWalletAddress(network.id.value, network.derivationPath.value)
walletManager.getWalletAddress(network.rawId, network.derivationPath.value)
} catch (exception: Exception) {
Timber.e(exception)
null
@ -84,7 +84,7 @@ internal class WcSolanaNetwork(
}
override fun toCAIP2(network: Network): CAIP2? {
val blockchain = Blockchain.fromId(network.id.value)
val blockchain = Blockchain.fromId(network.rawId)
val chainId = when (blockchain) {
Blockchain.Solana -> MAINNET_CHAIN_ID
Blockchain.SolanaTestnet -> TESTNET_CHAIN_ID