Updated on 2026-08-14
This commit is contained in:
parent
a30e44b1cf
commit
0907ba002c
23 changed files with 217 additions and 65 deletions
|
|
@ -26,6 +26,7 @@ dependencies {
|
||||||
implementation(project(":features:referral:presentation"))
|
implementation(project(":features:referral:presentation"))
|
||||||
implementation(project(":features:referral:domain"))
|
implementation(project(":features:referral:domain"))
|
||||||
implementation(project(":features:referral:data"))
|
implementation(project(":features:referral:data"))
|
||||||
|
implementation(project(":features:swap:api"))
|
||||||
implementation(project(":features:swap:presentation"))
|
implementation(project(":features:swap:presentation"))
|
||||||
implementation(project(":features:swap:domain"))
|
implementation(project(":features:swap:domain"))
|
||||||
implementation(project(":features:swap:data"))
|
implementation(project(":features:swap:data"))
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import com.tangem.blockchain.common.Blockchain
|
||||||
import com.tangem.blockchain.common.TransactionData
|
import com.tangem.blockchain.common.TransactionData
|
||||||
import com.tangem.common.extensions.isZero
|
import com.tangem.common.extensions.isZero
|
||||||
import com.tangem.domain.common.extensions.toNetworkId
|
import com.tangem.domain.common.extensions.toNetworkId
|
||||||
|
import com.tangem.feature.swap.api.SwapFeatureToggleManager
|
||||||
import com.tangem.feature.swap.domain.SwapInteractor
|
import com.tangem.feature.swap.domain.SwapInteractor
|
||||||
import com.tangem.tap.features.wallet.models.Currency
|
import com.tangem.tap.features.wallet.models.Currency
|
||||||
import com.tangem.tap.features.wallet.models.PendingTransaction
|
import com.tangem.tap.features.wallet.models.PendingTransaction
|
||||||
|
|
@ -36,22 +37,26 @@ data class WalletData(
|
||||||
return exchangeManager.availableForSell(currency)
|
return exchangeManager.availableForSell(currency)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isAvailableToSwap(swapInteractor: SwapInteractor, isExchangeFeatureOn: Boolean): Boolean {
|
fun isAvailableToSwap(
|
||||||
|
swapFeatureToggleManager: SwapFeatureToggleManager,
|
||||||
|
swapInteractor: SwapInteractor,
|
||||||
|
): Boolean {
|
||||||
|
val isOptimismEnabled =
|
||||||
|
currency.blockchain.id == Blockchain.Optimism.id && swapFeatureToggleManager.isOptimismSwapEnabled
|
||||||
return swapInteractor.isAvailableToSwap(currency.blockchain.toNetworkId()) &&
|
return swapInteractor.isAvailableToSwap(currency.blockchain.toNetworkId()) &&
|
||||||
currency.blockchain.id != Blockchain.Optimism.id && // disable optimism blockchain for now
|
isOptimismEnabled &&
|
||||||
isExchangeFeatureOn &&
|
|
||||||
!currency.isCustomCurrency(null)
|
!currency.isCustomCurrency(null)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getAvailableActions(
|
fun getAvailableActions(
|
||||||
swapInteractor: SwapInteractor,
|
swapInteractor: SwapInteractor,
|
||||||
exchangeManager: CurrencyExchangeManager,
|
exchangeManager: CurrencyExchangeManager,
|
||||||
isExchangeFeatureOn: Boolean,
|
swapFeatureToggleManager: SwapFeatureToggleManager,
|
||||||
): Set<CurrencyAction> {
|
): Set<CurrencyAction> {
|
||||||
return setOfNotNull(
|
return setOfNotNull(
|
||||||
if (isAvailableToBuy(exchangeManager)) CurrencyAction.Buy else null,
|
if (isAvailableToBuy(exchangeManager)) CurrencyAction.Buy else null,
|
||||||
if (isAvailableToSell(exchangeManager)) CurrencyAction.Sell else null,
|
if (isAvailableToSell(exchangeManager)) CurrencyAction.Sell else null,
|
||||||
if (isAvailableToSwap(swapInteractor, isExchangeFeatureOn)) CurrencyAction.Swap else null,
|
if (isAvailableToSwap(swapFeatureToggleManager, swapInteractor)) CurrencyAction.Swap else null,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import com.tangem.common.extensions.guard
|
||||||
import com.tangem.core.analytics.Analytics
|
import com.tangem.core.analytics.Analytics
|
||||||
import com.tangem.domain.common.TapWorkarounds.derivationStyle
|
import com.tangem.domain.common.TapWorkarounds.derivationStyle
|
||||||
import com.tangem.domain.common.extensions.withMainContext
|
import com.tangem.domain.common.extensions.withMainContext
|
||||||
|
import com.tangem.feature.swap.api.SwapFeatureToggleManager
|
||||||
import com.tangem.feature.swap.domain.SwapInteractor
|
import com.tangem.feature.swap.domain.SwapInteractor
|
||||||
import com.tangem.sdk.extensions.dpToPx
|
import com.tangem.sdk.extensions.dpToPx
|
||||||
import com.tangem.tap.common.SnackbarHandler
|
import com.tangem.tap.common.SnackbarHandler
|
||||||
|
|
@ -75,6 +76,9 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details),
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var swapInteractor: SwapInteractor
|
lateinit var swapInteractor: SwapInteractor
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var swapFeatureToggleManager: SwapFeatureToggleManager
|
||||||
|
|
||||||
private lateinit var pendingTransactionAdapter: PendingTransactionsAdapter
|
private lateinit var pendingTransactionAdapter: PendingTransactionsAdapter
|
||||||
private lateinit var warningMessagesAdapter: WalletDetailWarningMessagesAdapter
|
private lateinit var warningMessagesAdapter: WalletDetailWarningMessagesAdapter
|
||||||
|
|
||||||
|
|
@ -290,7 +294,7 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details),
|
||||||
WalletAction.DialogAction.ChooseTradeActionDialog(
|
WalletAction.DialogAction.ChooseTradeActionDialog(
|
||||||
buyAllowed = selectedWallet.isAvailableToBuy(exchangeManager),
|
buyAllowed = selectedWallet.isAvailableToBuy(exchangeManager),
|
||||||
sellAllowed = selectedWallet.isAvailableToSell(exchangeManager),
|
sellAllowed = selectedWallet.isAvailableToSell(exchangeManager),
|
||||||
swapAllowed = selectedWallet.isAvailableToSwap(swapInteractor, isExchangeServiceFeatureOn),
|
swapAllowed = selectedWallet.isAvailableToSwap(swapFeatureToggleManager, swapInteractor),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -298,7 +302,7 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details),
|
||||||
val actions = selectedWallet.getAvailableActions(
|
val actions = selectedWallet.getAvailableActions(
|
||||||
swapInteractor = swapInteractor,
|
swapInteractor = swapInteractor,
|
||||||
exchangeManager = exchangeManager,
|
exchangeManager = exchangeManager,
|
||||||
isExchangeFeatureOn = isExchangeServiceFeatureOn,
|
swapFeatureToggleManager = swapFeatureToggleManager,
|
||||||
)
|
)
|
||||||
binding.rowButtons.updateButtonsVisibility(
|
binding.rowButtons.updateButtonsVisibility(
|
||||||
actions = actions,
|
actions = actions,
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import coil.size.Scale
|
||||||
import com.tangem.core.analytics.Analytics
|
import com.tangem.core.analytics.Analytics
|
||||||
import com.tangem.core.ui.fragments.setStatusBarColor
|
import com.tangem.core.ui.fragments.setStatusBarColor
|
||||||
import com.tangem.core.ui.utils.OneTouchClickListener
|
import com.tangem.core.ui.utils.OneTouchClickListener
|
||||||
|
import com.tangem.feature.swap.api.SwapFeatureToggleManager
|
||||||
import com.tangem.feature.swap.domain.SwapInteractor
|
import com.tangem.feature.swap.domain.SwapInteractor
|
||||||
import com.tangem.tap.MainActivity
|
import com.tangem.tap.MainActivity
|
||||||
import com.tangem.tap.common.analytics.events.MainScreen
|
import com.tangem.tap.common.analytics.events.MainScreen
|
||||||
|
|
@ -56,6 +57,9 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber<Walle
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var swapInteractor: SwapInteractor
|
lateinit var swapInteractor: SwapInteractor
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var swapFeatureToggleManager: SwapFeatureToggleManager
|
||||||
|
|
||||||
private lateinit var warningsAdapter: WarningMessagesAdapter
|
private lateinit var warningsAdapter: WarningMessagesAdapter
|
||||||
|
|
||||||
private val binding: FragmentWalletBinding by viewBinding(FragmentWalletBinding::bind)
|
private val binding: FragmentWalletBinding by viewBinding(FragmentWalletBinding::bind)
|
||||||
|
|
@ -170,6 +174,7 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber<Walle
|
||||||
}
|
}
|
||||||
|
|
||||||
walletView.swapInteractor = swapInteractor
|
walletView.swapInteractor = swapInteractor
|
||||||
|
walletView.swapFeatureToggleManager = swapFeatureToggleManager
|
||||||
|
|
||||||
walletView.onNewState(state)
|
walletView.onNewState(state)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -135,6 +135,7 @@ class SingleWalletView : WalletView() {
|
||||||
isExchangeServiceFeatureEnabled: Boolean,
|
isExchangeServiceFeatureEnabled: Boolean,
|
||||||
) {
|
) {
|
||||||
val swapInteractor = this.swapInteractor ?: return
|
val swapInteractor = this.swapInteractor ?: return
|
||||||
|
val swapFeatureToggleManager = this.swapFeatureToggleManager ?: return
|
||||||
|
|
||||||
val exchangeManager = store.state.globalState.exchangeManager
|
val exchangeManager = store.state.globalState.exchangeManager
|
||||||
binding?.rowButtons?.apply {
|
binding?.rowButtons?.apply {
|
||||||
|
|
@ -154,7 +155,7 @@ class SingleWalletView : WalletView() {
|
||||||
val actions = walletData.getAvailableActions(
|
val actions = walletData.getAvailableActions(
|
||||||
swapInteractor = swapInteractor,
|
swapInteractor = swapInteractor,
|
||||||
exchangeManager = exchangeManager,
|
exchangeManager = exchangeManager,
|
||||||
isExchangeFeatureOn = isExchangeServiceFeatureEnabled,
|
swapFeatureToggleManager = swapFeatureToggleManager,
|
||||||
)
|
)
|
||||||
binding?.rowButtons?.updateButtonsVisibility(
|
binding?.rowButtons?.updateButtonsVisibility(
|
||||||
actions = actions,
|
actions = actions,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package com.tangem.tap.features.wallet.ui.wallet
|
package com.tangem.tap.features.wallet.ui.wallet
|
||||||
|
|
||||||
|
import com.tangem.feature.swap.api.SwapFeatureToggleManager
|
||||||
import com.tangem.feature.swap.domain.SwapInteractor
|
import com.tangem.feature.swap.domain.SwapInteractor
|
||||||
import com.tangem.tap.features.wallet.redux.WalletState
|
import com.tangem.tap.features.wallet.redux.WalletState
|
||||||
import com.tangem.tap.features.wallet.ui.WalletFragment
|
import com.tangem.tap.features.wallet.ui.WalletFragment
|
||||||
|
|
@ -8,6 +9,7 @@ import com.tangem.wallet.databinding.FragmentWalletBinding
|
||||||
abstract class WalletView {
|
abstract class WalletView {
|
||||||
|
|
||||||
var swapInteractor: SwapInteractor? = null
|
var swapInteractor: SwapInteractor? = null
|
||||||
|
var swapFeatureToggleManager: SwapFeatureToggleManager? = null
|
||||||
|
|
||||||
protected var fragment: WalletFragment? = null
|
protected var fragment: WalletFragment? = null
|
||||||
protected var binding: FragmentWalletBinding? = null
|
protected var binding: FragmentWalletBinding? = null
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import com.google.firebase.crashlytics.FirebaseCrashlytics
|
||||||
import com.tangem.Message
|
import com.tangem.Message
|
||||||
import com.tangem.blockchain.blockchains.ethereum.EthereumTransactionExtras
|
import com.tangem.blockchain.blockchains.ethereum.EthereumTransactionExtras
|
||||||
import com.tangem.blockchain.blockchains.ethereum.EthereumWalletManager
|
import com.tangem.blockchain.blockchains.ethereum.EthereumWalletManager
|
||||||
|
import com.tangem.blockchain.blockchains.optimism.OptimismWalletManager
|
||||||
import com.tangem.blockchain.common.Amount
|
import com.tangem.blockchain.common.Amount
|
||||||
import com.tangem.blockchain.common.Blockchain
|
import com.tangem.blockchain.common.Blockchain
|
||||||
import com.tangem.blockchain.common.BlockchainSdkError
|
import com.tangem.blockchain.common.BlockchainSdkError
|
||||||
|
|
@ -155,56 +156,31 @@ class TransactionManagerImpl(
|
||||||
val blockchain = requireNotNull(Blockchain.fromNetworkId(networkId)) { "blockchain not found" }
|
val blockchain = requireNotNull(Blockchain.fromNetworkId(networkId)) { "blockchain not found" }
|
||||||
val walletManager = getActualWalletManager(blockchain, derivationPath)
|
val walletManager = getActualWalletManager(blockchain, derivationPath)
|
||||||
if (walletManager is EthereumWalletManager) {
|
if (walletManager is EthereumWalletManager) {
|
||||||
val gasLimit = getGasLimit(
|
if (walletManager is OptimismWalletManager) {
|
||||||
evmWalletManager = walletManager,
|
return getFeeForOptimismBlockchain(
|
||||||
|
walletManager = walletManager,
|
||||||
|
amount = createAmount(amountToSend, currencyToSend, blockchain),
|
||||||
|
destinationAddress = destinationAddress,
|
||||||
|
data = data,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return getFeeForEthereumBlockchain(
|
||||||
|
walletManager = walletManager,
|
||||||
blockchain = blockchain,
|
blockchain = blockchain,
|
||||||
amount = amountToSend,
|
amountToSend = amountToSend,
|
||||||
currency = currencyToSend,
|
currency = currencyToSend,
|
||||||
destinationAddress = destinationAddress,
|
destinationAddress = destinationAddress,
|
||||||
data = data,
|
data = data,
|
||||||
).let {
|
increaseBy = increaseBy,
|
||||||
if (increaseBy != null && increaseBy != 0) {
|
)
|
||||||
it.multiply(increaseBy.toBigInteger()).divide(BigInteger("100"))
|
|
||||||
} else {
|
|
||||||
it
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return when (val gasPrice = walletManager.getGasPrice()) {
|
|
||||||
is Result.Success -> {
|
|
||||||
val fee = gasLimit.multiply(gasPrice.data).toBigDecimal(
|
|
||||||
scale = blockchain.decimals(),
|
|
||||||
mathContext = MathContext(blockchain.decimals(), RoundingMode.HALF_EVEN),
|
|
||||||
)
|
|
||||||
ProxyFee(
|
|
||||||
gasLimit = gasLimit,
|
|
||||||
fee = ProxyAmount(
|
|
||||||
currencySymbol = blockchain.currency,
|
|
||||||
value = fee,
|
|
||||||
decimals = blockchain.decimals(),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
is Result.Failure -> {
|
|
||||||
error(gasPrice.error.message ?: gasPrice.error.customMessage)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
val fee = (walletManager as? TransactionSender)?.getFee(
|
return getFeeForBlockchain(
|
||||||
amount = createAmount(amountToSend, currencyToSend, blockchain),
|
walletManager = walletManager,
|
||||||
destination = destinationAddress,
|
amountToSend = amountToSend,
|
||||||
) ?: error("Cannot cast to TransactionSender")
|
currency = currencyToSend,
|
||||||
when (fee) {
|
blockchain = blockchain,
|
||||||
is Result.Success -> {
|
destinationAddress = destinationAddress,
|
||||||
// for not EVM blockchains set gasLimit ZERO for now
|
)
|
||||||
return ProxyFee(
|
|
||||||
gasLimit = BigInteger.ZERO,
|
|
||||||
fee = convertToProxyAmount(fee.data.firstOrNull() ?: error("no fee found")),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
is Result.Failure -> {
|
|
||||||
error(fee.error.message ?: fee.error.customMessage)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -217,6 +193,100 @@ class TransactionManagerImpl(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private suspend fun getFeeForBlockchain(
|
||||||
|
walletManager: WalletManager,
|
||||||
|
amountToSend: BigDecimal,
|
||||||
|
currency: Currency,
|
||||||
|
blockchain: Blockchain,
|
||||||
|
destinationAddress: String,
|
||||||
|
): ProxyFee {
|
||||||
|
val fee = (walletManager as? TransactionSender)?.getFee(
|
||||||
|
amount = createAmount(amountToSend, currency, blockchain),
|
||||||
|
destination = destinationAddress,
|
||||||
|
) ?: error("Cannot cast to TransactionSender")
|
||||||
|
return when (fee) {
|
||||||
|
is Result.Success -> {
|
||||||
|
// for not EVM blockchains set gasLimit ZERO for now
|
||||||
|
ProxyFee(
|
||||||
|
gasLimit = BigInteger.ZERO,
|
||||||
|
fee = convertToProxyAmount(fee.data.firstOrNull() ?: error("no fee found")),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
is Result.Failure -> {
|
||||||
|
error(fee.error.message ?: fee.error.customMessage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("LongParameterList")
|
||||||
|
private suspend fun getFeeForEthereumBlockchain(
|
||||||
|
walletManager: EthereumWalletManager,
|
||||||
|
blockchain: Blockchain,
|
||||||
|
amountToSend: BigDecimal,
|
||||||
|
currency: Currency,
|
||||||
|
destinationAddress: String,
|
||||||
|
data: String?,
|
||||||
|
increaseBy: Int?,
|
||||||
|
): ProxyFee {
|
||||||
|
val gasLimit = getGasLimit(
|
||||||
|
evmWalletManager = walletManager,
|
||||||
|
blockchain = blockchain,
|
||||||
|
amount = amountToSend,
|
||||||
|
currency = currency,
|
||||||
|
destinationAddress = destinationAddress,
|
||||||
|
data = data,
|
||||||
|
).let {
|
||||||
|
if (increaseBy != null && increaseBy != 0) {
|
||||||
|
it.multiply(increaseBy.toBigInteger()).divide(BigInteger("100"))
|
||||||
|
} else {
|
||||||
|
it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return when (val gasPrice = walletManager.getGasPrice()) {
|
||||||
|
is Result.Success -> {
|
||||||
|
val fee = gasLimit.multiply(gasPrice.data).toBigDecimal(
|
||||||
|
scale = blockchain.decimals(),
|
||||||
|
mathContext = MathContext(blockchain.decimals(), RoundingMode.HALF_EVEN),
|
||||||
|
)
|
||||||
|
ProxyFee(
|
||||||
|
gasLimit = gasLimit,
|
||||||
|
fee = ProxyAmount(
|
||||||
|
currencySymbol = blockchain.currency,
|
||||||
|
value = fee,
|
||||||
|
decimals = blockchain.decimals(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
is Result.Failure -> {
|
||||||
|
error(gasPrice.error.message ?: gasPrice.error.customMessage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun getFeeForOptimismBlockchain(
|
||||||
|
walletManager: OptimismWalletManager,
|
||||||
|
amount: Amount,
|
||||||
|
destinationAddress: String,
|
||||||
|
data: String?,
|
||||||
|
): ProxyFee {
|
||||||
|
val fee = if (data.isNullOrEmpty()) {
|
||||||
|
walletManager.getFee(amount, destinationAddress)
|
||||||
|
} else {
|
||||||
|
walletManager.getFee(amount, destinationAddress, data)
|
||||||
|
}
|
||||||
|
when (fee) {
|
||||||
|
is Result.Success -> {
|
||||||
|
return ProxyFee(
|
||||||
|
gasLimit = walletManager.gasLimit ?: BigInteger.ZERO,
|
||||||
|
fee = convertToProxyAmount(fee.data.lastOrNull() ?: error("no fee found")),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
is Result.Failure -> {
|
||||||
|
error(fee.error.message ?: fee.error.customMessage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Suppress("LongParameterList")
|
@Suppress("LongParameterList")
|
||||||
private suspend fun getGasLimit(
|
private suspend fun getGasLimit(
|
||||||
evmWalletManager: EthereumWalletManager,
|
evmWalletManager: EthereumWalletManager,
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,6 @@
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"name": "INACTIVE_TEST_FEATURE_ENABLED",
|
"name": "OPTIMISM_SWAP_FEATURE_ENABLED",
|
||||||
"version": "undefined"
|
"version": "4.3.1"
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "ACTIVE2_TEST_FEATURE_ENABLED",
|
|
||||||
"version": "1.0.0"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
@ -42,7 +42,7 @@ internal class DevFeatureTogglesManager(
|
||||||
.toMutableMap()
|
.toMutableMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isFeatureEnabled(name: String): Boolean = featureTogglesMap.any { it.key == name }
|
override fun isFeatureEnabled(name: String): Boolean = featureTogglesMap[name] ?: false
|
||||||
|
|
||||||
override fun getFeatureToggles(): Map<String, Boolean> = featureTogglesMap
|
override fun getFeatureToggles(): Map<String, Boolean> = featureTogglesMap
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ internal class ProdFeatureTogglesManager(
|
||||||
.associateToggles(currentVersion = versionProvider.get() ?: "")
|
.associateToggles(currentVersion = versionProvider.get() ?: "")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isFeatureEnabled(name: String): Boolean = featureToggles.any { it.key == name }
|
override fun isFeatureEnabled(name: String): Boolean = featureToggles[name] ?: false
|
||||||
|
|
||||||
@VisibleForTesting(otherwise = VisibleForTesting.NONE)
|
@VisibleForTesting(otherwise = VisibleForTesting.NONE)
|
||||||
fun getProdFeatureToggles() = featureToggles
|
fun getProdFeatureToggles() = featureToggles
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,7 @@ internal class DevFeatureTogglesManagerTest {
|
||||||
@Test
|
@Test
|
||||||
fun `get feature availability if feature toggle exists`() {
|
fun `get feature availability if feature toggle exists`() {
|
||||||
val featureToggles = mutableMapOf(
|
val featureToggles = mutableMapOf(
|
||||||
"INACTIVE_TEST_FEATURE_ENABLED" to false,
|
"INACTIVE_TEST_FEATURE_ENABLED" to true,
|
||||||
"ACTIVE2_TEST_FEATURE_ENABLED" to true,
|
"ACTIVE2_TEST_FEATURE_ENABLED" to true,
|
||||||
)
|
)
|
||||||
manager.setFeatureToggles(featureToggles)
|
manager.setFeatureToggles(featureToggles)
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,7 @@ internal class ProdFeatureTogglesManagerTest {
|
||||||
@Test
|
@Test
|
||||||
fun `get feature availability if feature toggle exists`() {
|
fun `get feature availability if feature toggle exists`() {
|
||||||
val featureToggles = mapOf(
|
val featureToggles = mapOf(
|
||||||
"INACTIVE_TEST_FEATURE_ENABLED" to false,
|
"INACTIVE_TEST_FEATURE_ENABLED" to true,
|
||||||
"ACTIVE2_TEST_FEATURE_ENABLED" to true,
|
"ACTIVE2_TEST_FEATURE_ENABLED" to true,
|
||||||
)
|
)
|
||||||
manager.setProdFeatureToggles(featureToggles)
|
manager.setProdFeatureToggles(featureToggles)
|
||||||
|
|
|
||||||
1
features/swap/api/.gitignore
vendored
Normal file
1
features/swap/api/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
/build
|
||||||
14
features/swap/api/build.gradle.kts
Normal file
14
features/swap/api/build.gradle.kts
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
plugins {
|
||||||
|
alias(deps.plugins.android.library)
|
||||||
|
alias(deps.plugins.kotlin.android)
|
||||||
|
alias(deps.plugins.kotlin.kapt)
|
||||||
|
alias(deps.plugins.kotlin.serialization)
|
||||||
|
alias(deps.plugins.hilt.android)
|
||||||
|
id("configuration")
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
/** DI */
|
||||||
|
implementation(deps.hilt.android)
|
||||||
|
kapt(deps.hilt.kapt)
|
||||||
|
}
|
||||||
2
features/swap/api/src/main/AndroidManifest.xml
Normal file
2
features/swap/api/src/main/AndroidManifest.xml
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest package="com.tangem.feature.swap.api" />
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
package com.tangem.feature.swap.api
|
||||||
|
|
||||||
|
/** Feature toggles manager of "swap" feature */
|
||||||
|
interface SwapFeatureToggleManager {
|
||||||
|
|
||||||
|
val isOptimismSwapEnabled: Boolean
|
||||||
|
}
|
||||||
|
|
@ -10,6 +10,7 @@ plugins {
|
||||||
dependencies {
|
dependencies {
|
||||||
/** Core modules */
|
/** Core modules */
|
||||||
implementation(project(":core:analytics"))
|
implementation(project(":core:analytics"))
|
||||||
|
implementation(project(":core:featuretoggles"))
|
||||||
implementation(project(":core:utils"))
|
implementation(project(":core:utils"))
|
||||||
implementation(project(":core:ui"))
|
implementation(project(":core:ui"))
|
||||||
|
|
||||||
|
|
@ -27,6 +28,9 @@ dependencies {
|
||||||
implementation(deps.compose.coil)
|
implementation(deps.compose.coil)
|
||||||
implementation(deps.compose.constraintLayout)
|
implementation(deps.compose.constraintLayout)
|
||||||
|
|
||||||
|
/** Api */
|
||||||
|
implementation(project(":features:swap:api"))
|
||||||
|
|
||||||
/** Domain */
|
/** Domain */
|
||||||
implementation(project(":features:swap:domain"))
|
implementation(project(":features:swap:domain"))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
package com.tangem.feature.swap.di
|
||||||
|
|
||||||
|
import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
|
||||||
|
import com.tangem.feature.swap.api.SwapFeatureToggleManager
|
||||||
|
import com.tangem.feature.swap.toggles.DefaultFeatureTogglesManager
|
||||||
|
import dagger.Module
|
||||||
|
import dagger.Provides
|
||||||
|
import dagger.hilt.InstallIn
|
||||||
|
import dagger.hilt.android.components.ActivityRetainedComponent
|
||||||
|
import dagger.hilt.android.scopes.ActivityRetainedScoped
|
||||||
|
|
||||||
|
@Module
|
||||||
|
@InstallIn(ActivityRetainedComponent::class)
|
||||||
|
internal object SwapFeatureTogglesManagerModule {
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@ActivityRetainedScoped
|
||||||
|
fun provideSwapFeatureTogglesManager(featureTogglesManager: FeatureTogglesManager): SwapFeatureToggleManager {
|
||||||
|
return DefaultFeatureTogglesManager(featureTogglesManager)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.tangem.feature.swap.toggles
|
||||||
|
|
||||||
|
import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
|
||||||
|
|
||||||
|
/** Feature toggles manager implementation of "swap" feature */
|
||||||
|
class DefaultFeatureTogglesManager(
|
||||||
|
private val featureTogglesManager: FeatureTogglesManager,
|
||||||
|
) : InnerSwapFeatureTogglesManager {
|
||||||
|
|
||||||
|
override val isOptimismSwapEnabled: Boolean
|
||||||
|
get() = featureTogglesManager.isFeatureEnabled(name = "OPTIMISM_SWAP_FEATURE_ENABLED")
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
package com.tangem.feature.swap.toggles
|
||||||
|
|
||||||
|
import com.tangem.feature.swap.api.SwapFeatureToggleManager
|
||||||
|
|
||||||
|
/** Feature toggles manager of "swap" feature for internal logic */
|
||||||
|
internal interface InnerSwapFeatureTogglesManager : SwapFeatureToggleManager
|
||||||
|
|
@ -438,7 +438,7 @@ internal class SwapViewModel @Inject constructor(
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val INITIAL_AMOUNT = ""
|
private const val INITIAL_AMOUNT = ""
|
||||||
private const val UPDATE_DELAY = 10000L
|
private const val UPDATE_DELAY = 1000000L
|
||||||
private const val DEBOUNCE_AMOUNT_DELAY = 1000L
|
private const val DEBOUNCE_AMOUNT_DELAY = 1000L
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -68,7 +68,7 @@ kotlinSerialization = "1.4.1"
|
||||||
# endregion Other libraries
|
# endregion Other libraries
|
||||||
|
|
||||||
# region Tangem
|
# region Tangem
|
||||||
tangemBlockchainSdk = "develop-176"
|
tangemBlockchainSdk = "develop-177"
|
||||||
# tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds
|
# tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds
|
||||||
tangemCardSdk = "develop-204"
|
tangemCardSdk = "develop-204"
|
||||||
# tangemCardSdk = "0.0.1" # Keep it! - used for local builds
|
# tangemCardSdk = "0.0.1" # Keep it! - used for local builds
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ include(":libs:auth")
|
||||||
include(":features:referral:data")
|
include(":features:referral:data")
|
||||||
include(":features:referral:domain")
|
include(":features:referral:domain")
|
||||||
include(":features:referral:presentation")
|
include(":features:referral:presentation")
|
||||||
|
include(":features:swap:api")
|
||||||
include(":features:swap:data")
|
include(":features:swap:data")
|
||||||
include(":features:swap:domain")
|
include(":features:swap:domain")
|
||||||
include(":features:swap:presentation")
|
include(":features:swap:presentation")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue