Updated on 2026-08-14

This commit is contained in:
Tangem 2024-02-12 15:50:29 +03:00
commit cef36091da
379 changed files with 8948 additions and 8976 deletions

View file

@ -1,39 +0,0 @@
package com.tangem.domain
import com.tangem.common.module.ModuleError
import com.tangem.common.module.ModuleErrorCode
import com.tangem.common.module.ModuleMessage
/**
[REDACTED_AUTHOR]
* All DomainError descendants must use their own range of codes, but no more than 999 error codes for each.
*/
sealed interface DomainModuleMessage : ModuleMessage
sealed class DomainModuleError(
subCode: Int,
override val message: String,
override val data: Any?,
) : DomainModuleMessage, ModuleError() {
override val code: Int = ModuleErrorCode.DOMAIN + subCode
companion object {
// base code used for all errors in the module
internal const val ERROR_CODE_ADD_CUSTOM_TOKEN = 100
// const val CODE_ANY_OTHER = 200..299, 300..399 etc
}
}
sealed class AddCustomTokenError(
subCode: Int = 0,
message: String? = null,
data: Any? = null,
) : DomainModuleError(
subCode = ERROR_CODE_ADD_CUSTOM_TOKEN + subCode,
message = message ?: this::class.java.simpleName,
data = data,
) {
object FieldIsEmpty : AddCustomTokenError()
object InvalidContractAddress : AddCustomTokenError()
}

View file

@ -80,6 +80,11 @@ fun Blockchain.Companion.fromNetworkId(networkId: String): Blockchain? {
"vechain/test" -> Blockchain.VeChainTestnet
"aptos" -> Blockchain.Aptos
"aptos/test" -> Blockchain.AptosTestnet
"" -> Blockchain.Playa3ull // FIXME
"shibarium" -> Blockchain.Shibarium
"shibarium/test" -> Blockchain.ShibariumTestnet
"algorand" -> Blockchain.Algorand
"algorand/test" -> Blockchain.AlgorandTestnet
else -> null
}
}
@ -161,6 +166,11 @@ fun Blockchain.toNetworkId(): String {
Blockchain.VeChainTestnet -> "vechain/test"
Blockchain.Aptos -> "aptos"
Blockchain.AptosTestnet -> "aptos/test"
Blockchain.Playa3ull -> "" // FIXME
Blockchain.Shibarium -> "shibarium"
Blockchain.ShibariumTestnet -> "shibarium/test"
Blockchain.Algorand -> "algorand"
Blockchain.AlgorandTestnet -> "algorand/test"
}
}
@ -212,6 +222,11 @@ fun Blockchain.toCoinId(): String {
Blockchain.VeChain, Blockchain.VeChainTestnet -> "vechain"
Blockchain.Aptos -> "aptos"
Blockchain.AptosTestnet -> "aptos/test"
Blockchain.Playa3ull -> "" // FIXME
Blockchain.Shibarium -> "bone-shibaswap"
Blockchain.ShibariumTestnet -> "bone-shibaswap/test"
Blockchain.Algorand -> "algorand"
Blockchain.AlgorandTestnet -> "algorand/test"
Blockchain.Unknown -> "unknown"
}
}
@ -240,5 +255,5 @@ private const val NODL_AMOUNT_TO_CREATE_ACCOUNT = 1.5
private val excludedBlockchains = listOf(
Blockchain.Unknown,
Blockchain.Ducatus,
Blockchain.Aptos,
Blockchain.Playa3ull,
)

View file

@ -2,8 +2,6 @@ package com.tangem.domain.tokens
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.Token
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.wallets.models.UserWallet
import org.rekotlin.Action
sealed interface TokensAction : Action {
@ -13,14 +11,6 @@ sealed interface TokensAction : Action {
object ManageAccess : SetArgs
object ReadAccess : SetArgs
}
data class SaveChanges(
val currentTokens: List<CryptoCurrency.Token>,
val currentCoins: List<CryptoCurrency.Coin>,
val changedTokens: List<CryptoCurrency.Token>,
val changedCoins: List<CryptoCurrency.Coin>,
val userWallet: UserWallet,
) : TokensAction
}
data class TokenWithBlockchain(val token: Token, val blockchain: Blockchain)

View file

@ -5,12 +5,12 @@ import arrow.core.raise.either
import arrow.core.raise.ensureNotNull
import arrow.core.right
import com.squareup.moshi.Moshi
import com.tangem.blockchain.blockchains.polkadot.ExistentialDepositProvider
import com.tangem.blockchain.blockchains.solana.RentProvider
import com.tangem.blockchain.common.*
import com.tangem.blockchain.common.address.Address
import com.tangem.blockchain.common.address.AddressType
import com.tangem.blockchain.common.address.EstimationFeeAddressFactory
import com.tangem.blockchain.common.datastorage.BlockchainDataStorage
import com.tangem.blockchain.common.transaction.Fee
import com.tangem.blockchain.common.transaction.TransactionFee
import com.tangem.blockchain.common.txhistory.TransactionHistoryRequest
@ -40,21 +40,22 @@ import timber.log.Timber
import java.math.BigDecimal
import java.util.EnumSet
@Suppress("LargeClass", "TooManyFunctions")
@Suppress("LargeClass", "TooManyFunctions", "LongParameterList")
// FIXME: Move to its own module and make internal
@Deprecated("Inject the WalletManagerFacade interface using DI instead")
class DefaultWalletManagersFacade(
private val walletManagersStore: WalletManagersStore,
private val userWalletsStore: UserWalletsStore,
configManager: ConfigManager,
mnemonic: Mnemonic,
assetReader: AssetReader,
moshi: Moshi,
configManager: ConfigManager,
blockchainDataStorage: BlockchainDataStorage,
) : WalletManagersFacade {
private val demoConfig by lazy { DemoConfig() }
private val resultFactory by lazy { UpdateWalletManagerResultFactory() }
private val walletManagerFactory by lazy { WalletManagerFactory(configManager) }
private val walletManagerFactory by lazy { WalletManagerFactory(configManager, blockchainDataStorage) }
private val sdkTokenConverter by lazy { SdkTokenConverter() }
private val txHistoryStateConverter by lazy { SdkTransactionHistoryStateConverter() }
private val txHistoryItemConverter by lazy { SdkTransactionHistoryItemConverter(assetReader, moshi) }
@ -275,7 +276,11 @@ class DefaultWalletManagersFacade(
resultFactory.getResult(walletManager)
} catch (e: BlockchainSdkError.AccountNotFound) {
resultFactory.getNoAccountResult(walletManager = walletManager, customMessage = e.customMessage)
resultFactory.getNoAccountResult(
walletManager = walletManager,
customMessage = e.customMessage,
amountToCreateAccount = e.amountToCreateAccount,
)
} catch (e: Throwable) {
Timber.w(e, "Unable to update a wallet manager for: ${walletManager.wallet.blockchain}")
@ -287,7 +292,11 @@ class DefaultWalletManagersFacade(
return try {
resultFactory.getResult(walletManager)
} catch (e: BlockchainSdkError.AccountNotFound) {
resultFactory.getNoAccountResult(walletManager = walletManager, customMessage = e.customMessage)
resultFactory.getNoAccountResult(
walletManager = walletManager,
customMessage = e.customMessage,
amountToCreateAccount = e.amountToCreateAccount,
)
} catch (e: Throwable) {
Timber.w(e, "Unable to update a wallet manager for: ${walletManager.wallet.blockchain}")
@ -321,6 +330,16 @@ class DefaultWalletManagersFacade(
return walletManager
}
@Deprecated("Will be removed in future")
override suspend fun getOrCreateWalletManager(userWalletId: UserWalletId, network: Network): WalletManager? {
val blockchain = Blockchain.fromId(network.id.value)
return getOrCreateWalletManager(
userWalletId = userWalletId,
blockchain = blockchain,
derivationPath = network.derivationPath.value,
)
}
@Deprecated("Will be removed in future")
override suspend fun getStoredWalletManagers(userWalletId: UserWalletId): List<WalletManager> {
return walletManagersStore.getAllSync(userWalletId)
@ -376,63 +395,6 @@ class DefaultWalletManagersFacade(
}
}
@Deprecated("Will be removed in future")
override suspend fun getExistentialDeposit(userWalletId: UserWalletId, network: Network): BigDecimal? {
val manager = getOrCreateWalletManager(
userWalletId = userWalletId,
network = network,
)
return if (manager is ExistentialDepositProvider) manager.getExistentialDeposit() else null
}
@Deprecated("Will be removed in future")
override suspend fun getDustValue(userWalletId: UserWalletId, network: Network): BigDecimal? {
val blockchain = Blockchain.fromId(network.id.value)
val manager = getOrCreateWalletManager(
userWalletId = userWalletId,
blockchain = blockchain,
derivationPath = network.derivationPath.value,
)
return manager?.dustValue
}
@Deprecated("Will be removed in future")
override suspend fun getReserveAmount(userWalletId: UserWalletId, network: Network): BigDecimal? {
val manager = getOrCreateWalletManager(
userWalletId = userWalletId,
network = network,
)
return if (manager is ReserveAmountProvider) manager.getReserveAmount() else null
}
@Deprecated("Will be removed in future")
override suspend fun checkIfAccountFunded(userWalletId: UserWalletId, network: Network, address: String): Boolean {
val manager = getOrCreateWalletManager(
userWalletId = userWalletId,
network = network,
)
return if (manager is ReserveAmountProvider) manager.isAccountFunded(address) else true
}
@Deprecated("Will be removed in future")
override suspend fun checkUtxoAmountLimit(
userWalletId: UserWalletId,
network: Network,
amount: BigDecimal,
fee: BigDecimal,
): UtxoAmountLimit? {
val manager = getOrCreateWalletManager(
userWalletId = userWalletId,
network = network,
)
return if (manager is UtxoAmountLimitProvider) manager.checkUtxoAmountLimit(amount, fee) else null
}
@Deprecated("Will be removed in future")
override fun getAll(userWalletId: UserWalletId): Flow<List<WalletManager>> {
return walletManagersStore.getAll(userWalletId)
@ -605,13 +567,4 @@ class DefaultWalletManagersFacade(
walletManager.addTokens(tokensToAdd)
}
private suspend fun getOrCreateWalletManager(userWalletId: UserWalletId, network: Network): WalletManager? {
val blockchain = Blockchain.fromId(network.id.value)
return getOrCreateWalletManager(
userWalletId = userWalletId,
blockchain = blockchain,
derivationPath = network.derivationPath.value,
)
}
}

View file

@ -108,6 +108,9 @@ interface WalletManagersFacade {
derivationPath: String?,
): WalletManager?
@Deprecated("Will be removed in future")
suspend fun getOrCreateWalletManager(userWalletId: UserWalletId, network: Network): WalletManager?
@Deprecated("Will be removed in future")
suspend fun getStoredWalletManagers(userWalletId: UserWalletId): List<WalletManager>
@ -136,47 +139,6 @@ interface WalletManagersFacade {
*/
suspend fun getRentInfo(userWalletId: UserWalletId, network: Network): CryptoCurrencyWarning.Rent?
/**
* Returns value which indicates if the account balance drops below the existential deposit value, it will be
* deactivated and any remaining funds will be destroyed.
*
* [REDACTED_TODO_COMMENT]
*/
@Deprecated("Will be removed in future")
suspend fun getExistentialDeposit(userWalletId: UserWalletId, network: Network): BigDecimal?
@Deprecated("Will be removed in future")
suspend fun getDustValue(userWalletId: UserWalletId, network: Network): BigDecimal?
/**
* Returns reserve amount which is required to create an account
*
* [REDACTED_TODO_COMMENT]
*/
@Deprecated("Will be removed in future")
suspend fun getReserveAmount(userWalletId: UserWalletId, network: Network): BigDecimal?
/**
* Returns true if account with [address] was reserved with minimum amount
*
* [REDACTED_TODO_COMMENT]
*/
@Deprecated("Will be removed in future")
suspend fun checkIfAccountFunded(userWalletId: UserWalletId, network: Network, address: String): Boolean
/**
* Checks if transaction amount is within the UTXO limit
*
* [REDACTED_TODO_COMMENT]
*/
@Deprecated("Will be removed in future")
suspend fun checkUtxoAmountLimit(
userWalletId: UserWalletId,
network: Network,
amount: BigDecimal,
fee: BigDecimal,
): UtxoAmountLimit?
@Deprecated("Will be removed in future")
fun getAll(userWalletId: UserWalletId): Flow<List<WalletManager>>

View file

@ -40,13 +40,17 @@ internal class UpdateWalletManagerResultFactory {
)
}
fun getNoAccountResult(walletManager: WalletManager, customMessage: String): UpdateWalletManagerResult {
fun getNoAccountResult(
walletManager: WalletManager,
customMessage: String,
amountToCreateAccount: BigDecimal?,
): UpdateWalletManagerResult {
val wallet = walletManager.wallet
val blockchain = wallet.blockchain
val firstWalletToken = wallet.getTokens().firstOrNull()
val amountToCreateAccount = blockchain.amountToCreateAccount(firstWalletToken)
val amount = amountToCreateAccount ?: blockchain.amountToCreateAccount(firstWalletToken)
return if (amountToCreateAccount == null) {
return if (amount == null) {
Timber.w("Unable to get required amount to create account for: $blockchain")
UpdateWalletManagerResult.Unreachable(
selectedAddress = wallet.address,
@ -56,7 +60,7 @@ internal class UpdateWalletManagerResultFactory {
UpdateWalletManagerResult.NoAccount(
selectedAddress = wallet.address,
addresses = getAvailableAddresses(wallet.addresses),
amountToCreateAccount = amountToCreateAccount,
amountToCreateAccount = amount,
errorMessage = customMessage,
)
}

View file

@ -3,7 +3,7 @@ package com.tangem.domain.walletmanager.utils
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.DerivationParams
import com.tangem.blockchain.common.WalletManager
import com.tangem.blockchain.common.WalletManagerFactory
import com.tangem.blockchain.common.datastorage.BlockchainDataStorage
import com.tangem.crypto.hdWallet.DerivationPath
import com.tangem.datasource.config.ConfigManager
import com.tangem.domain.common.DerivationStyleProvider
@ -11,13 +11,12 @@ import com.tangem.domain.common.extensions.makeWalletManagerForApp
import com.tangem.domain.common.util.derivationStyleProvider
import com.tangem.domain.models.scan.ScanResponse
import timber.log.Timber
import com.tangem.blockchain.common.WalletManagerFactory as BlockchainWalletManagerFactory
internal class WalletManagerFactory(
private val configManager: ConfigManager,
) {
internal class WalletManagerFactory(configManager: ConfigManager, blockchainDataStorage: BlockchainDataStorage) {
private val sdkWalletManagerFactory by lazy {
WalletManagerFactory(configManager.config.blockchainSdkConfig)
BlockchainWalletManagerFactory(configManager.config.blockchainSdkConfig, blockchainDataStorage)
}
fun createWalletManager(