Updated on 2026-08-14
This commit is contained in:
parent
b27e8171fb
commit
4ea8243da3
19 changed files with 375 additions and 126 deletions
|
|
@ -7,6 +7,7 @@ import com.tangem.blockchainsdk.utils.fromNetworkId
|
|||
import com.tangem.blockchainsdk.utils.toBlockchain
|
||||
import com.tangem.blockchainsdk.utils.toCoinId
|
||||
import com.tangem.data.common.network.NetworkFactory
|
||||
import com.tangem.domain.models.account.DerivationIndex
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
|
|
@ -18,7 +19,7 @@ class CryptoCurrencyFactory(
|
|||
private val excludedBlockchains: ExcludedBlockchains,
|
||||
) {
|
||||
|
||||
private val networkFactory by lazy(LazyThreadSafetyMode.NONE) { NetworkFactory(excludedBlockchains) }
|
||||
val networkFactory by lazy(LazyThreadSafetyMode.NONE) { NetworkFactory(excludedBlockchains) }
|
||||
|
||||
@Suppress("LongParameterList") // Yep, it's long
|
||||
fun createToken(
|
||||
|
|
@ -89,6 +90,7 @@ class CryptoCurrencyFactory(
|
|||
blockchain: Blockchain,
|
||||
extraDerivationPath: String?,
|
||||
userWallet: UserWallet,
|
||||
accountIndex: DerivationIndex? = null,
|
||||
): CryptoCurrency.Coin? {
|
||||
if (blockchain == Blockchain.Unknown) {
|
||||
Timber.e("Unable to map the SDK token to the domain token with Unknown blockchain")
|
||||
|
|
@ -99,6 +101,7 @@ class CryptoCurrencyFactory(
|
|||
blockchain = blockchain,
|
||||
extraDerivationPath = extraDerivationPath,
|
||||
userWallet = userWallet,
|
||||
accountIndex = accountIndex,
|
||||
) ?: return null
|
||||
|
||||
return createCoin(network)
|
||||
|
|
|
|||
|
|
@ -5,13 +5,12 @@ import com.tangem.blockchainsdk.utils.toBlockchain
|
|||
import com.tangem.blockchainsdk.utils.toNetworkId
|
||||
import com.tangem.data.common.account.WalletAccountsFetcher
|
||||
import com.tangem.data.common.tokens.getDefaultWalletBlockchains
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import com.tangem.datasource.api.tangemTech.models.account.toUserTokensResponse
|
||||
import com.tangem.datasource.local.token.UserTokensResponseStore
|
||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
|
||||
import com.tangem.domain.card.common.util.cardTypesResolver
|
||||
import com.tangem.domain.demo.models.DemoConfig
|
||||
import com.tangem.domain.models.account.DerivationIndex
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
|
|
@ -140,15 +139,32 @@ internal class DefaultCardCryptoCurrencyFactory(
|
|||
userWallet: UserWallet,
|
||||
networks: Set<Network>,
|
||||
): Map<Network, List<CryptoCurrency>> {
|
||||
val response = getUserTokensResponse(userWalletId = userWallet.walletId)
|
||||
?: return emptyMap()
|
||||
val existingNetworkWithCurrencies = if (accountsFeatureToggles.isFeatureEnabled) {
|
||||
val response = walletAccountsFetcher.getSaved(userWallet.walletId)
|
||||
?: return emptyMap()
|
||||
|
||||
val existingNetworkWithCurrencies = responseCryptoCurrenciesFactory.createCurrencies(
|
||||
tokens = response.tokens.filter { token ->
|
||||
networks.any { it.backendId == token.networkId && it.derivationPath.value == token.derivationPath }
|
||||
},
|
||||
userWallet = userWallet,
|
||||
)
|
||||
response.accounts.flatMapTo(hashSetOf()) { accountDTO ->
|
||||
responseCryptoCurrenciesFactory.createCurrencies(
|
||||
tokens = accountDTO.tokens.orEmpty().filter { token ->
|
||||
networks.any {
|
||||
it.backendId == token.networkId && it.derivationPath.value == token.derivationPath
|
||||
}
|
||||
},
|
||||
userWallet = userWallet,
|
||||
accountIndex = DerivationIndex(accountDTO.derivationIndex).getOrNull(),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
val response = userTokensResponseStore.getSyncOrNull(userWalletId = userWallet.walletId)
|
||||
?: return emptyMap()
|
||||
|
||||
responseCryptoCurrenciesFactory.createCurrencies(
|
||||
tokens = response.tokens.filter { token ->
|
||||
networks.any { it.backendId == token.networkId && it.derivationPath.value == token.derivationPath }
|
||||
},
|
||||
userWallet = userWallet,
|
||||
)
|
||||
}
|
||||
.groupBy(CryptoCurrency::network)
|
||||
|
||||
return networks.associateWith { emptyList<CryptoCurrency>() } + existingNetworkWithCurrencies
|
||||
|
|
@ -158,24 +174,29 @@ internal class DefaultCardCryptoCurrencyFactory(
|
|||
userWallet: UserWallet,
|
||||
rawIds: Set<Network.RawID>,
|
||||
): Map<Network.RawID, List<CryptoCurrency>> {
|
||||
val response = getUserTokensResponse(userWalletId = userWallet.walletId)
|
||||
?: return emptyMap()
|
||||
|
||||
val networkIds = rawIds.map { it.toBlockchain().toNetworkId() }
|
||||
|
||||
return responseCryptoCurrenciesFactory.createCurrencies(
|
||||
tokens = response.tokens.filter { token -> token.networkId in networkIds },
|
||||
userWallet = userWallet,
|
||||
)
|
||||
.groupBy { it.network.id.rawId }
|
||||
}
|
||||
|
||||
private suspend fun getUserTokensResponse(userWalletId: UserWalletId): UserTokensResponse? {
|
||||
return if (accountsFeatureToggles.isFeatureEnabled) {
|
||||
walletAccountsFetcher.getSaved(userWalletId)?.toUserTokensResponse()
|
||||
val response = walletAccountsFetcher.getSaved(userWallet.walletId)
|
||||
?: return emptyMap()
|
||||
|
||||
response.accounts.flatMapTo(hashSetOf()) { accountDTO ->
|
||||
responseCryptoCurrenciesFactory.createCurrencies(
|
||||
tokens = accountDTO.tokens.orEmpty().filter { token -> token.networkId in networkIds },
|
||||
userWallet = userWallet,
|
||||
accountIndex = DerivationIndex(accountDTO.derivationIndex).getOrNull(),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
userTokensResponseStore.getSyncOrNull(userWalletId = userWalletId)
|
||||
val response = userTokensResponseStore.getSyncOrNull(userWalletId = userWallet.walletId)
|
||||
?: return emptyMap()
|
||||
|
||||
responseCryptoCurrenciesFactory.createCurrencies(
|
||||
tokens = response.tokens.filter { token -> token.networkId in networkIds },
|
||||
userWallet = userWallet,
|
||||
)
|
||||
}
|
||||
.groupBy { it.network.id.rawId }
|
||||
}
|
||||
|
||||
private fun getSingleWalletCurrencies(userWallet: UserWallet.Cold): SingleWalletCurrencies {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import com.tangem.blockchainsdk.utils.toCoinId
|
|||
import com.tangem.data.common.network.NetworkFactory
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import com.tangem.domain.card.common.util.cardTypesResolver
|
||||
import com.tangem.domain.models.account.DerivationIndex
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import timber.log.Timber
|
||||
|
|
@ -24,19 +25,31 @@ class ResponseCryptoCurrenciesFactory @Inject constructor(
|
|||
.first { it.id.value == currencyId }
|
||||
}
|
||||
|
||||
fun createCurrencies(response: UserTokensResponse, userWallet: UserWallet): List<CryptoCurrency> {
|
||||
return createCurrencies(tokens = response.tokens, userWallet = userWallet)
|
||||
fun createCurrencies(
|
||||
response: UserTokensResponse,
|
||||
userWallet: UserWallet,
|
||||
accountIndex: DerivationIndex? = null,
|
||||
): List<CryptoCurrency> {
|
||||
return createCurrencies(tokens = response.tokens, userWallet = userWallet, accountIndex = accountIndex)
|
||||
}
|
||||
|
||||
fun createCurrencies(tokens: List<UserTokensResponse.Token>, userWallet: UserWallet): List<CryptoCurrency> {
|
||||
fun createCurrencies(
|
||||
tokens: List<UserTokensResponse.Token>,
|
||||
userWallet: UserWallet,
|
||||
accountIndex: DerivationIndex? = null,
|
||||
): List<CryptoCurrency> {
|
||||
return tokens
|
||||
.asSequence()
|
||||
.mapNotNull { createCurrency(it, userWallet) }
|
||||
.mapNotNull { createCurrency(it, userWallet, accountIndex) }
|
||||
.distinctBy(CryptoCurrency::id)
|
||||
.toList()
|
||||
}
|
||||
|
||||
fun createCurrency(responseToken: UserTokensResponse.Token, userWallet: UserWallet): CryptoCurrency? {
|
||||
fun createCurrency(
|
||||
responseToken: UserTokensResponse.Token,
|
||||
userWallet: UserWallet,
|
||||
accountIndex: DerivationIndex? = null,
|
||||
): CryptoCurrency? {
|
||||
var blockchain = Blockchain.fromNetworkId(responseToken.networkId)
|
||||
if (blockchain == null || blockchain == Blockchain.Unknown) {
|
||||
Timber.e("Unable to find a blockchain with the network ID: ${responseToken.networkId}")
|
||||
|
|
@ -49,9 +62,9 @@ class ResponseCryptoCurrenciesFactory @Inject constructor(
|
|||
|
||||
val sdkToken = createSdkToken(responseToken)
|
||||
return if (sdkToken == null) {
|
||||
createCoin(blockchain, responseToken, userWallet)
|
||||
createCoin(blockchain, responseToken, userWallet, accountIndex)
|
||||
} else {
|
||||
createToken(blockchain, sdkToken, responseToken.derivationPath, userWallet)
|
||||
createToken(blockchain, sdkToken, responseToken.derivationPath, userWallet, accountIndex)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -71,11 +84,13 @@ class ResponseCryptoCurrenciesFactory @Inject constructor(
|
|||
blockchain: Blockchain,
|
||||
responseToken: UserTokensResponse.Token,
|
||||
userWallet: UserWallet,
|
||||
accountIndex: DerivationIndex?,
|
||||
): CryptoCurrency.Coin? {
|
||||
val network = networkFactory.create(
|
||||
blockchain = blockchain,
|
||||
extraDerivationPath = responseToken.derivationPath,
|
||||
userWallet = userWallet,
|
||||
accountIndex = accountIndex,
|
||||
) ?: return null
|
||||
|
||||
return CryptoCurrency.Coin(
|
||||
|
|
@ -106,11 +121,13 @@ class ResponseCryptoCurrenciesFactory @Inject constructor(
|
|||
sdkToken: Token,
|
||||
responseDerivationPath: String?,
|
||||
userWallet: UserWallet,
|
||||
accountIndex: DerivationIndex?,
|
||||
): CryptoCurrency.Token? {
|
||||
val network = networkFactory.create(
|
||||
blockchain = blockchain,
|
||||
extraDerivationPath = responseDerivationPath,
|
||||
userWallet = userWallet,
|
||||
accountIndex = accountIndex,
|
||||
) ?: return null
|
||||
|
||||
val id = getTokenId(network, sdkToken)
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import com.tangem.domain.models.wallet.UserWallet
|
|||
import com.tangem.domain.wallets.derivations.derivationStyleProvider
|
||||
import javax.inject.Inject
|
||||
|
||||
// TODO: [REDACTED_JIRA]
|
||||
class UserTokensResponseFactory @Inject constructor() {
|
||||
|
||||
fun createUserTokensResponse(
|
||||
|
|
|
|||
|
|
@ -7,10 +7,12 @@ import com.tangem.blockchainsdk.utils.ExcludedBlockchains
|
|||
import com.tangem.blockchainsdk.utils.toBlockchain
|
||||
import com.tangem.blockchainsdk.utils.toNetworkId
|
||||
import com.tangem.domain.card.common.extensions.canHandleToken
|
||||
import com.tangem.domain.models.account.DerivationIndex
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.wallets.derivations.DerivationStyleProvider
|
||||
import com.tangem.domain.wallets.derivations.derivationStyleProvider
|
||||
import com.tangem.lib.crypto.derivation.toMutable
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
@ -21,6 +23,7 @@ import javax.inject.Inject
|
|||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@Suppress("LargeClass")
|
||||
class NetworkFactory @Inject constructor(
|
||||
private val excludedBlockchains: ExcludedBlockchains,
|
||||
) {
|
||||
|
|
@ -32,13 +35,19 @@ class NetworkFactory @Inject constructor(
|
|||
* @param extraDerivationPath extra derivation path
|
||||
* @param userWallet user wallet
|
||||
*/
|
||||
fun create(blockchain: Blockchain, extraDerivationPath: String?, userWallet: UserWallet): Network? {
|
||||
fun create(
|
||||
blockchain: Blockchain,
|
||||
extraDerivationPath: String?,
|
||||
userWallet: UserWallet,
|
||||
accountIndex: DerivationIndex? = null,
|
||||
): Network? {
|
||||
return create(
|
||||
blockchain = blockchain,
|
||||
derivationPath = createDerivationPath(
|
||||
blockchain = blockchain,
|
||||
extraDerivationPath = extraDerivationPath,
|
||||
cardDerivationStyleProvider = userWallet.derivationStyleProvider,
|
||||
accountIndex = accountIndex,
|
||||
),
|
||||
canHandleTokens = userWallet.canHandleToken(
|
||||
blockchain = blockchain,
|
||||
|
|
@ -80,6 +89,7 @@ class NetworkFactory @Inject constructor(
|
|||
extraDerivationPath: String?,
|
||||
derivationStyleProvider: DerivationStyleProvider?,
|
||||
canHandleTokens: Boolean,
|
||||
accountIndex: DerivationIndex? = null,
|
||||
): Network? {
|
||||
return create(
|
||||
blockchain = blockchain,
|
||||
|
|
@ -87,6 +97,7 @@ class NetworkFactory @Inject constructor(
|
|||
blockchain = blockchain,
|
||||
extraDerivationPath = extraDerivationPath,
|
||||
cardDerivationStyleProvider = derivationStyleProvider,
|
||||
accountIndex = accountIndex,
|
||||
),
|
||||
canHandleTokens = canHandleTokens,
|
||||
)
|
||||
|
|
@ -134,10 +145,11 @@ class NetworkFactory @Inject constructor(
|
|||
blockchain: Blockchain,
|
||||
extraDerivationPath: String?,
|
||||
cardDerivationStyleProvider: DerivationStyleProvider?,
|
||||
accountIndex: DerivationIndex? = null,
|
||||
): Network.DerivationPath {
|
||||
if (cardDerivationStyleProvider == null) return Network.DerivationPath.None
|
||||
|
||||
val defaultDerivationPath = getDefaultDerivationPath(blockchain, cardDerivationStyleProvider)
|
||||
val defaultDerivationPath = getDefaultDerivationPath(blockchain, cardDerivationStyleProvider, accountIndex)
|
||||
|
||||
return if (extraDerivationPath.isNullOrBlank()) {
|
||||
if (defaultDerivationPath.isNullOrBlank()) {
|
||||
|
|
@ -146,10 +158,11 @@ class NetworkFactory @Inject constructor(
|
|||
Network.DerivationPath.Card(defaultDerivationPath)
|
||||
}
|
||||
} else {
|
||||
if (extraDerivationPath == defaultDerivationPath) {
|
||||
Network.DerivationPath.Card(defaultDerivationPath)
|
||||
} else {
|
||||
val isMainIndexOrNull = accountIndex == null || accountIndex == DerivationIndex.Main
|
||||
if (extraDerivationPath != defaultDerivationPath && isMainIndexOrNull) {
|
||||
Network.DerivationPath.Custom(extraDerivationPath)
|
||||
} else {
|
||||
Network.DerivationPath.Card(extraDerivationPath)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -157,8 +170,19 @@ class NetworkFactory @Inject constructor(
|
|||
private fun getDefaultDerivationPath(
|
||||
blockchain: Blockchain,
|
||||
derivationStyleProvider: DerivationStyleProvider,
|
||||
accountIndex: DerivationIndex?,
|
||||
): String? {
|
||||
return blockchain.derivationPath(derivationStyleProvider.getDerivationStyle())?.rawPath
|
||||
val default = blockchain.derivationPath(derivationStyleProvider.getDerivationStyle())
|
||||
?: return null
|
||||
|
||||
return if (accountIndex == null || accountIndex == DerivationIndex.Main) {
|
||||
default
|
||||
} else {
|
||||
default.toMutable()
|
||||
.replaceAccountNode(value = accountIndex.value.toLong(), blockchain = blockchain)
|
||||
.apply()
|
||||
}
|
||||
.rawPath
|
||||
}
|
||||
|
||||
private fun getNetworkStandardType(blockchain: Blockchain): Network.StandardType {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue