Updated on 2026-08-14

This commit is contained in:
Tangem 2026-01-13 13:14:21 +02:00
parent 38aaf7fd56
commit 7e1fcc18d1
9 changed files with 71 additions and 14 deletions

View file

@ -73,6 +73,13 @@ class P2PEthPoolIntegration(
override val rewardClaiming: RewardClaiming = RewardClaiming.AUTO
// Legal URLs
override val legalUrls: StakingLegalUrls = StakingLegalUrls(
termsOfServiceUrl = TERMS_OF_SERVICE_URL,
privacyPolicyUrl = PRIVACY_POLICY_URL,
)
override fun getCurrentToken(rawCurrencyId: CryptoCurrency.RawID?): YieldToken = token
private fun calculateMaximumStakeAmount(): BigDecimal? {
@ -88,5 +95,8 @@ class P2PEthPoolIntegration(
private const val MIN_COOLDOWN_DAYS = 1
private const val MAX_COOLDOWN_DAYS = 4
private val DEFAULT_MINIMUM_STAKE = BigDecimal("0.01")
private const val TERMS_OF_SERVICE_URL = "https://www.p2p.org/terms-of-use"
private const val PRIVACY_POLICY_URL = "https://www.p2p.org/privacy-policy"
}
}

View file

@ -59,6 +59,13 @@ class StakeKitIntegration(
override val rewardClaiming: RewardClaiming = yield.metadata.rewardClaiming.toRewardClaiming()
// Legal URLs
override val legalUrls: StakingLegalUrls = StakingLegalUrls(
termsOfServiceUrl = TERMS_OF_SERVICE_URL,
privacyPolicyUrl = PRIVACY_POLICY_URL,
)
// Basic
override fun getCurrentToken(rawCurrencyId: CryptoCurrency.RawID?): YieldToken =
@ -98,4 +105,9 @@ class StakeKitIntegration(
Yield.Metadata.RewardClaiming.UNKNOWN -> RewardClaiming.UNKNOWN
}
}
companion object {
private const val TERMS_OF_SERVICE_URL = "https://docs.yield.xyz/docs/terms-of-use"
private const val PRIVACY_POLICY_URL = "https://docs.yield.xyz/docs/privacy-policy"
}
}

View file

@ -51,6 +51,10 @@ sealed interface StakingIntegration {
val rewardClaiming: RewardClaiming
// Legal URLs
val legalUrls: StakingLegalUrls
// Basic
fun getCurrentToken(rawCurrencyId: CryptoCurrency.RawID?): YieldToken

View file

@ -0,0 +1,6 @@
package com.tangem.domain.staking.model
data class StakingLegalUrls(
val termsOfServiceUrl: String,
val privacyPolicyUrl: String,
)

View file

@ -71,8 +71,14 @@ internal sealed class StakingStates {
val onInfoClick: (InfoType) -> Unit,
val yieldBalance: InnerYieldBalanceState,
val pullToRefreshConfig: PullToRefreshConfig,
val legalUrls: LegalUrls,
) : InitialInfoState()
data class LegalUrls(
val termsOfServiceUrl: String,
val privacyPolicyUrl: String,
)
data class Empty(
override val isPrimaryButtonEnabled: Boolean = false,
) : InitialInfoState()

View file

@ -60,6 +60,10 @@ internal object InitialStakingStatePreview {
onInfoClick = {},
yieldBalance = InnerYieldBalanceState.Empty,
pullToRefreshConfig = PullToRefreshConfig(isRefreshing = false, onRefresh = {}),
legalUrls = StakingStates.InitialInfoState.LegalUrls(
termsOfServiceUrl = "https://docs.yield.xyz/docs/terms-of-use",
privacyPolicyUrl = "https://docs.yield.xyz/docs/privacy-policy",
),
)
val stateWithYield = defaultState.copy(

View file

@ -104,6 +104,10 @@ internal class SetInitialDataStateTransformer(
onRefresh = { clickIntents.onRefreshSwipe(it.value) },
isRefreshing = false,
),
legalUrls = StakingStates.InitialInfoState.LegalUrls(
termsOfServiceUrl = integration.legalUrls.termsOfServiceUrl,
privacyPolicyUrl = integration.legalUrls.privacyPolicyUrl,
),
)
}

View file

@ -112,7 +112,10 @@ internal fun StakingInitialInfoContent(
item(STAKE_PRIMARY_BUTTON_KEY) {
SpacerH12()
StakeButtonBlock(buttonState)
StakeButtonBlock(
legalUrls = state.legalUrls,
buttonState = buttonState,
)
}
}
}
@ -386,7 +389,10 @@ private fun RowScope.StakingBalanceIcon(balance: BalanceState, icon: Int?, iconT
}
@Composable
private fun StakeButtonBlock(buttonState: NavigationButtonsState) {
private fun StakeButtonBlock(
legalUrls: StakingStates.InitialInfoState.LegalUrls,
buttonState: NavigationButtonsState,
) {
val state = buttonState as? NavigationButtonsState.Data
val primaryButton = state?.primaryButton
@ -395,7 +401,12 @@ private fun StakeButtonBlock(buttonState: NavigationButtonsState) {
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12),
) {
state?.onTextClick?.let { StakingTosText(it) }
state?.let { buttonsState ->
StakingTosText(
onTermsOfServiceClick = { buttonsState.onTextClick(legalUrls.termsOfServiceUrl) },
onPrivacyPolicyClick = { buttonsState.onTextClick(legalUrls.privacyPolicyUrl) },
)
}
NavigationPrimaryButton(primaryButton = primaryButton)
}
}

View file

@ -15,11 +15,8 @@ import com.tangem.features.staking.impl.R
private const val TERMS_OF_USE_KEY = "termsOfUse"
private const val PRIVACY_POLICY_KEY = "privacyPolicy"
private const val TERMS_OF_USE_URL = "https://docs.yield.xyz/docs/terms-of-use#/"
private const val PRIVACY_POLICY_URL = "https://docs.yield.xyz/docs/privacy-policy#/"
@Composable
internal fun StakingTosText(onTextClick: (String) -> Unit) {
internal fun StakingTosText(onTermsOfServiceClick: () -> Unit, onPrivacyPolicyClick: () -> Unit) {
val termsOfUse = stringResourceSafe(R.string.common_terms_of_use)
val privacyPolicy = stringResourceSafe(R.string.common_privacy_policy)
val tosText = stringResourceSafe(R.string.staking_legal, termsOfUse, privacyPolicy)
@ -45,20 +42,23 @@ internal fun StakingTosText(onTextClick: (String) -> Unit) {
textAlign = TextAlign.Center,
),
onClick = { offset ->
clickableAnnotation.getStringAnnotations(
val isTermsOfUseClicked = clickableAnnotation.getStringAnnotations(
tag = TERMS_OF_USE_KEY,
start = offset,
end = offset,
).firstOrNull()?.let {
onTextClick(TERMS_OF_USE_URL)
}
).any()
clickableAnnotation.getStringAnnotations(
val isPrivacyPolicyClicked = clickableAnnotation.getStringAnnotations(
tag = PRIVACY_POLICY_KEY,
start = offset,
end = offset,
).firstOrNull()?.let {
onTextClick(PRIVACY_POLICY_URL)
).any()
if (isTermsOfUseClicked) {
onTermsOfServiceClick()
}
if (isPrivacyPolicyClicked) {
onPrivacyPolicyClick()
}
},
modifier = Modifier.testTag(StakingDetailsScreenTestTags.TOS_TEXT),