Updated on 2026-08-14
This commit is contained in:
parent
193dea813e
commit
ca286232ba
13 changed files with 111 additions and 92 deletions
|
|
@ -219,7 +219,7 @@ internal class ChildFactory @Inject constructor(
|
|||
params = StakingComponent.Params(
|
||||
userWalletId = route.userWalletId,
|
||||
cryptoCurrencyId = route.cryptoCurrencyId,
|
||||
yield = route.yield,
|
||||
yieldId = route.yieldId,
|
||||
),
|
||||
componentFactory = stakingComponentFactory,
|
||||
)
|
||||
|
|
@ -376,7 +376,7 @@ internal class ChildFactory @Inject constructor(
|
|||
params = StakingComponent.Params(
|
||||
userWalletId = route.userWalletId,
|
||||
cryptoCurrencyId = route.cryptoCurrencyId,
|
||||
yield = route.yield,
|
||||
yieldId = route.yieldId,
|
||||
),
|
||||
componentFactory = stakingComponentFactory,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import com.tangem.domain.markets.TokenMarketParams
|
|||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.onramp.model.OnrampSource
|
||||
import com.tangem.domain.qrscanning.models.SourceType
|
||||
import com.tangem.domain.staking.model.stakekit.Yield
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import kotlinx.serialization.Serializable
|
||||
|
|
@ -257,8 +256,8 @@ sealed class AppRoute(val path: String) : Route {
|
|||
data class Staking(
|
||||
val userWalletId: UserWalletId,
|
||||
val cryptoCurrencyId: CryptoCurrency.ID,
|
||||
val yield: Yield,
|
||||
) : AppRoute(path = "/staking/${userWalletId.stringValue}/${cryptoCurrencyId.value}/${yield.id}")
|
||||
val yieldId: String,
|
||||
) : AppRoute(path = "/staking/${userWalletId.stringValue}/${cryptoCurrencyId.value}/$yieldId")
|
||||
|
||||
@Serializable
|
||||
data object PushNotification : AppRoute(path = "/push_notification")
|
||||
|
|
|
|||
|
|
@ -133,6 +133,12 @@ internal class DefaultStakingRepository(
|
|||
}
|
||||
}
|
||||
|
||||
override suspend fun getYield(yieldId: String): Yield {
|
||||
return withContext(dispatchers.io) {
|
||||
getEnabledYieldsSync().find { it.id == yieldId } ?: error("Staking is unavailable")
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getActions(
|
||||
userWalletId: UserWalletId,
|
||||
cryptoCurrency: CryptoCurrency,
|
||||
|
|
|
|||
|
|
@ -20,4 +20,10 @@ class GetYieldUseCase(
|
|||
.catch { stakingRepository.getYield(cryptoCurrencyId, symbol) }
|
||||
.mapLeft { stakingErrorResolver.resolve(it) }
|
||||
}
|
||||
|
||||
suspend operator fun invoke(yieldId: String): Either<StakingError, Yield> {
|
||||
return Either
|
||||
.catch { stakingRepository.getYield(yieldId) }
|
||||
.mapLeft { stakingErrorResolver.resolve(it) }
|
||||
}
|
||||
}
|
||||
|
|
@ -33,6 +33,8 @@ interface StakingRepository {
|
|||
|
||||
suspend fun getYield(cryptoCurrencyId: CryptoCurrency.ID, symbol: String): Yield
|
||||
|
||||
suspend fun getYield(yieldId: String): Yield
|
||||
|
||||
suspend fun getStakingAvailability(userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency): StakingAvailability
|
||||
|
||||
suspend fun getActions(
|
||||
|
|
|
|||
|
|
@ -39,78 +39,9 @@ class MockStakingRepository : StakingRepository {
|
|||
rewardSchedule = Yield.Metadata.RewardSchedule.DAY,
|
||||
)
|
||||
|
||||
override suspend fun getYield(cryptoCurrencyId: CryptoCurrency.ID, symbol: String): Yield = Yield(
|
||||
id = "1",
|
||||
token = Token(
|
||||
name = "Solana",
|
||||
network = NetworkType.SOLANA,
|
||||
symbol = "SOL",
|
||||
decimals = 18,
|
||||
address = null,
|
||||
coinGeckoId = "solana",
|
||||
logoURI = null,
|
||||
isPoints = null,
|
||||
),
|
||||
tokens = listOf(),
|
||||
args = Yield.Args(
|
||||
enter = Yield.Args.Enter(
|
||||
addresses = Yield.Args.Enter.Addresses(
|
||||
address = AddressArgument(
|
||||
required = false,
|
||||
network = null,
|
||||
minimum = null,
|
||||
maximum = null,
|
||||
),
|
||||
additionalAddresses = mapOf(),
|
||||
),
|
||||
args = mapOf(),
|
||||
),
|
||||
exit = null,
|
||||
),
|
||||
status = Yield.Status(enter = false, exit = null),
|
||||
apy = 1.toBigDecimal(),
|
||||
rewardRate = 2.3,
|
||||
rewardType = Yield.RewardType.APR,
|
||||
metadata = Yield.Metadata(
|
||||
name = "Yield",
|
||||
logoUri = "",
|
||||
description = "",
|
||||
documentation = null,
|
||||
gasFeeToken = Token(
|
||||
name = "Solana",
|
||||
network = NetworkType.SOLANA,
|
||||
symbol = "SOL",
|
||||
decimals = 18,
|
||||
address = null,
|
||||
coinGeckoId = null,
|
||||
logoURI = null,
|
||||
isPoints = null,
|
||||
),
|
||||
token = Token(
|
||||
name = "Solana",
|
||||
network = NetworkType.SOLANA,
|
||||
symbol = "SOL",
|
||||
decimals = 18,
|
||||
address = null,
|
||||
coinGeckoId = null,
|
||||
logoURI = null,
|
||||
isPoints = null,
|
||||
),
|
||||
tokens = listOf(),
|
||||
type = "auto",
|
||||
rewardSchedule = Yield.Metadata.RewardSchedule.DAY,
|
||||
cooldownPeriod = Yield.Metadata.Period(days = 1),
|
||||
warmupPeriod = Yield.Metadata.Period(days = 1),
|
||||
rewardClaiming = Yield.Metadata.RewardClaiming.AUTO,
|
||||
defaultValidator = null,
|
||||
minimumStake = null,
|
||||
supportsMultipleValidators = false,
|
||||
revshare = Yield.Metadata.Enabled(enabled = false),
|
||||
fee = Yield.Metadata.Enabled(enabled = false),
|
||||
),
|
||||
validators = listOf(),
|
||||
isAvailable = false,
|
||||
)
|
||||
override suspend fun getYield(cryptoCurrencyId: CryptoCurrency.ID, symbol: String): Yield = yield
|
||||
|
||||
override suspend fun getYield(yieldId: String) = yield
|
||||
|
||||
override suspend fun getStakingAvailability(
|
||||
userWalletId: UserWalletId,
|
||||
|
|
@ -245,4 +176,79 @@ class MockStakingRepository : StakingRepository {
|
|||
override fun getStakingApproval(cryptoCurrency: CryptoCurrency): StakingApproval = StakingApproval.Empty
|
||||
|
||||
override suspend fun isAnyTokenStaked(userWalletId: UserWalletId): Boolean = false
|
||||
|
||||
private companion object {
|
||||
val yield = Yield(
|
||||
id = "1",
|
||||
token = Token(
|
||||
name = "Solana",
|
||||
network = NetworkType.SOLANA,
|
||||
symbol = "SOL",
|
||||
decimals = 18,
|
||||
address = null,
|
||||
coinGeckoId = "solana",
|
||||
logoURI = null,
|
||||
isPoints = null,
|
||||
),
|
||||
tokens = listOf(),
|
||||
args = Yield.Args(
|
||||
enter = Yield.Args.Enter(
|
||||
addresses = Yield.Args.Enter.Addresses(
|
||||
address = AddressArgument(
|
||||
required = false,
|
||||
network = null,
|
||||
minimum = null,
|
||||
maximum = null,
|
||||
),
|
||||
additionalAddresses = mapOf(),
|
||||
),
|
||||
args = mapOf(),
|
||||
),
|
||||
exit = null,
|
||||
),
|
||||
status = Yield.Status(enter = false, exit = null),
|
||||
apy = 1.toBigDecimal(),
|
||||
rewardRate = 2.3,
|
||||
rewardType = Yield.RewardType.APR,
|
||||
metadata = Yield.Metadata(
|
||||
name = "Yield",
|
||||
logoUri = "",
|
||||
description = "",
|
||||
documentation = null,
|
||||
gasFeeToken = Token(
|
||||
name = "Solana",
|
||||
network = NetworkType.SOLANA,
|
||||
symbol = "SOL",
|
||||
decimals = 18,
|
||||
address = null,
|
||||
coinGeckoId = null,
|
||||
logoURI = null,
|
||||
isPoints = null,
|
||||
),
|
||||
token = Token(
|
||||
name = "Solana",
|
||||
network = NetworkType.SOLANA,
|
||||
symbol = "SOL",
|
||||
decimals = 18,
|
||||
address = null,
|
||||
coinGeckoId = null,
|
||||
logoURI = null,
|
||||
isPoints = null,
|
||||
),
|
||||
tokens = listOf(),
|
||||
type = "auto",
|
||||
rewardSchedule = Yield.Metadata.RewardSchedule.DAY,
|
||||
cooldownPeriod = Yield.Metadata.Period(days = 1),
|
||||
warmupPeriod = Yield.Metadata.Period(days = 1),
|
||||
rewardClaiming = Yield.Metadata.RewardClaiming.AUTO,
|
||||
defaultValidator = null,
|
||||
minimumStake = null,
|
||||
supportsMultipleValidators = false,
|
||||
revshare = Yield.Metadata.Enabled(enabled = false),
|
||||
fee = Yield.Metadata.Enabled(enabled = false),
|
||||
),
|
||||
validators = listOf(),
|
||||
isAvailable = false,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -179,7 +179,7 @@ internal class TokenActionsHandler @AssistedInject constructor(
|
|||
AppRoute.Staking(
|
||||
userWalletId = cryptoCurrencyData.userWallet.walletId,
|
||||
cryptoCurrencyId = cryptoCurrencyData.status.currency.id,
|
||||
yield = yield,
|
||||
yieldId = yield.id,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package com.tangem.features.staking.api
|
|||
|
||||
import com.tangem.core.decompose.factory.ComponentFactory
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.domain.staking.model.stakekit.Yield
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
|
||||
|
|
@ -11,7 +10,7 @@ interface StakingComponent : ComposableContentComponent {
|
|||
data class Params(
|
||||
val userWalletId: UserWalletId,
|
||||
val cryptoCurrencyId: CryptoCurrency.ID,
|
||||
val yield: Yield,
|
||||
val yieldId: String,
|
||||
)
|
||||
|
||||
interface Factory : ComponentFactory<Params, StakingComponent>
|
||||
|
|
|
|||
|
|
@ -26,10 +26,7 @@ import com.tangem.domain.feedback.SaveBlockchainErrorUseCase
|
|||
import com.tangem.domain.feedback.SendFeedbackEmailUseCase
|
||||
import com.tangem.domain.feedback.models.BlockchainErrorInfo
|
||||
import com.tangem.domain.feedback.models.FeedbackEmailType
|
||||
import com.tangem.domain.staking.GetActionsUseCase
|
||||
import com.tangem.domain.staking.InvalidatePendingTransactionsUseCase
|
||||
import com.tangem.domain.staking.IsAnyTokenStakedUseCase
|
||||
import com.tangem.domain.staking.IsApproveNeededUseCase
|
||||
import com.tangem.domain.staking.*
|
||||
import com.tangem.domain.staking.analytics.StakeScreenSource
|
||||
import com.tangem.domain.staking.analytics.StakingAnalyticsEvent
|
||||
import com.tangem.domain.staking.model.StakingApproval
|
||||
|
|
@ -81,6 +78,7 @@ import kotlinx.collections.immutable.persistentListOf
|
|||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import timber.log.Timber
|
||||
import java.math.BigDecimal
|
||||
import java.util.concurrent.CopyOnWriteArrayList
|
||||
|
|
@ -119,6 +117,7 @@ internal class StakingModel @Inject constructor(
|
|||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase,
|
||||
private val getActionsUseCase: GetActionsUseCase,
|
||||
private val getYieldUseCase: GetYieldUseCase,
|
||||
private val paramsInterceptorHolder: ParamsInterceptorHolder,
|
||||
private val shareManager: ShareManager,
|
||||
@DelayedWork private val coroutineScope: CoroutineScope,
|
||||
|
|
@ -139,7 +138,11 @@ internal class StakingModel @Inject constructor(
|
|||
|
||||
private val cryptoCurrencyId: CryptoCurrency.ID = params.cryptoCurrencyId
|
||||
private val userWalletId: UserWalletId = params.userWalletId
|
||||
private val yield: Yield = params.yield
|
||||
private val yield: Yield = runBlocking {
|
||||
getYieldUseCase(params.yieldId).getOrElse {
|
||||
error("yield must be not null")
|
||||
}
|
||||
}
|
||||
|
||||
private var cryptoCurrencyStatus: CryptoCurrencyStatus by Delegates.notNull()
|
||||
private var processingActions: List<StakingAction> = emptyList()
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import com.tangem.common.routing.AppRoute
|
|||
import com.tangem.common.routing.AppRouter
|
||||
import com.tangem.core.navigation.share.ShareManager
|
||||
import com.tangem.core.navigation.url.UrlOpener
|
||||
import com.tangem.domain.staking.model.stakekit.Yield
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.feature.tokendetails.presentation.TokenDetailsFragment
|
||||
|
|
@ -39,12 +38,12 @@ internal class DefaultTokenDetailsRouter(
|
|||
)
|
||||
}
|
||||
|
||||
override fun openStaking(userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency, yield: Yield) {
|
||||
override fun openStaking(userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency, yieldId: String) {
|
||||
router.push(
|
||||
AppRoute.Staking(
|
||||
userWalletId = userWalletId,
|
||||
cryptoCurrencyId = cryptoCurrency.id,
|
||||
yield = yield,
|
||||
yieldId = yieldId,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package com.tangem.feature.tokendetails.presentation.router
|
||||
|
||||
import com.tangem.domain.staking.model.stakekit.Yield
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.features.tokendetails.navigation.TokenDetailsRouter
|
||||
|
|
@ -18,7 +17,7 @@ internal interface InnerTokenDetailsRouter : TokenDetailsRouter {
|
|||
|
||||
fun openTokenDetails(userWalletId: UserWalletId, currency: CryptoCurrency)
|
||||
|
||||
fun openStaking(userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency, yield: Yield)
|
||||
fun openStaking(userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency, yieldId: String)
|
||||
|
||||
fun openOnrampSuccess(externalTxId: String)
|
||||
}
|
||||
|
|
@ -994,7 +994,7 @@ internal class TokenDetailsViewModel @Inject constructor(
|
|||
error("Staking is unavailable for ${cryptoCurrency.name}")
|
||||
}
|
||||
|
||||
router.openStaking(userWalletId, cryptoCurrency, yield)
|
||||
router.openStaking(userWalletId, cryptoCurrency, yield.id)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -409,7 +409,7 @@ internal class WalletCurrencyActionsClickIntentsImplementor @Inject constructor(
|
|||
AppRoute.Staking(
|
||||
userWalletId = userWalletId,
|
||||
cryptoCurrencyId = cryptoCurrency.id,
|
||||
yield = yield ?: return@launch,
|
||||
yieldId = yield?.id ?: return@launch,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue