Updated on 2026-08-14

This commit is contained in:
Tangem 2026-06-04 10:40:41 +02:00
parent 3a5144403b
commit eeb74486ef
5 changed files with 89 additions and 186 deletions

View file

@ -237,11 +237,7 @@ enum class TangemMessageEffect(val isAnimatable: Boolean) {
/** Applies a message effect background to the [Modifier] based on the provided [messageEffect] and [radius] */ /** Applies a message effect background to the [Modifier] based on the provided [messageEffect] and [radius] */
@Composable @Composable
internal fun Modifier.messageEffectBackground( fun Modifier.messageEffectBackground(messageEffect: TangemMessageEffect, radius: Dp, contentColor: Color): Modifier {
messageEffect: TangemMessageEffect,
radius: Dp,
contentColor: Color,
): Modifier {
val isInDarkTheme = LocalIsInDarkTheme.current val isInDarkTheme = LocalIsInDarkTheme.current
val borderGradientColors = remember(messageEffect, isInDarkTheme) { messageEffect.getBorderGradient(isInDarkTheme) } val borderGradientColors = remember(messageEffect, isInDarkTheme) { messageEffect.getBorderGradient(isInDarkTheme) }
val gradientColors = remember(messageEffect, isInDarkTheme) { messageEffect.getColorGradient(isInDarkTheme) } val gradientColors = remember(messageEffect, isInDarkTheme) { messageEffect.getColorGradient(isInDarkTheme) }

View file

@ -85,7 +85,7 @@ import com.tangem.domain.transaction.error.OpenTrustlineError
import com.tangem.domain.transaction.error.SendTransactionError import com.tangem.domain.transaction.error.SendTransactionError
import com.tangem.domain.transaction.usecase.* import com.tangem.domain.transaction.usecase.*
import com.tangem.domain.txhistory.usecase.GetExplorerTransactionUrlUseCase import com.tangem.domain.txhistory.usecase.GetExplorerTransactionUrlUseCase
import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsCountUseCase import com.tangem.domain.txhistory.usecase.GetFixedTxHistoryItemsUseCase
import com.tangem.domain.wallets.usecase.GetExploreUrlUseCase import com.tangem.domain.wallets.usecase.GetExploreUrlUseCase
import com.tangem.domain.wallets.usecase.GetWalletIconUseCase import com.tangem.domain.wallets.usecase.GetWalletIconUseCase
import com.tangem.domain.wallets.usecase.GetExtendedPublicKeyForCurrencyUseCase import com.tangem.domain.wallets.usecase.GetExtendedPublicKeyForCurrencyUseCase
@ -197,7 +197,7 @@ internal class TokenDetailsModel @Inject constructor(
private val swapFeedbackUseCase: SwapFeedbackUseCase, private val swapFeedbackUseCase: SwapFeedbackUseCase,
private val swapFeatureToggles: SwapFeatureToggles, private val swapFeatureToggles: SwapFeatureToggles,
private val quickTopUpBlockFactory: QuickTopUpBlockFactory, private val quickTopUpBlockFactory: QuickTopUpBlockFactory,
private val getTxHistoryItemsCountUseCase: GetTxHistoryItemsCountUseCase, private val getFixedTxHistoryItemsUseCase: GetFixedTxHistoryItemsUseCase,
private val checkOnrampAvailabilityUseCase: CheckOnrampAvailabilityUseCase, private val checkOnrampAvailabilityUseCase: CheckOnrampAvailabilityUseCase,
) : Model(), ) : Model(),
TokenDetailsClickIntents, TokenDetailsClickIntents,
@ -1424,12 +1424,18 @@ internal class TokenDetailsModel @Inject constructor(
emit(null) emit(null)
return@flow return@flow
} }
val txCount = getTxHistoryItemsCountUseCase(userWalletId, cryptoCurrency) val isHistoryEmpty = getFixedTxHistoryItemsUseCase.getSync(
userWalletId = userWalletId,
currency = cryptoCurrency,
).fold(
ifLeft = { true },
ifRight = { it.isEmpty() },
)
val availability = checkOnrampAvailabilityUseCase(userWallet) val availability = checkOnrampAvailabilityUseCase(userWallet)
emit( emit(
quickTopUpBlockFactory.build( quickTopUpBlockFactory.build(
currencyStatus = status, currencyStatus = status,
isTxHistoryEmpty = txCount, isHistoryEmpty = isHistoryEmpty,
onrampAvailability = availability, onrampAvailability = availability,
onPresetClick = ::onQuickTopUpClick, onPresetClick = ::onQuickTopUpClick,
onOtherClick = ::onQuickTopUpOtherClick, onOtherClick = ::onQuickTopUpOtherClick,

View file

@ -7,7 +7,6 @@ import com.tangem.core.ui.extensions.stringReference
import com.tangem.domain.models.currency.CryptoCurrencyStatus import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.onramp.model.OnrampAvailability import com.tangem.domain.onramp.model.OnrampAvailability
import com.tangem.domain.onramp.model.error.OnrampError import com.tangem.domain.onramp.model.error.OnrampError
import com.tangem.domain.txhistory.models.TxHistoryStateError
import com.tangem.feature.tokendetails.presentation.tokendetails.state.QuickTopUpBlockUM import com.tangem.feature.tokendetails.presentation.tokendetails.state.QuickTopUpBlockUM
import com.tangem.features.tokendetails.TokenDetailsFeatureToggles import com.tangem.features.tokendetails.TokenDetailsFeatureToggles
import com.tangem.utils.extensions.isZero import com.tangem.utils.extensions.isZero
@ -21,7 +20,7 @@ internal class QuickTopUpBlockFactory @Inject constructor(
fun build( fun build(
currencyStatus: CryptoCurrencyStatus, currencyStatus: CryptoCurrencyStatus,
isTxHistoryEmpty: Either<TxHistoryStateError, Int>, isHistoryEmpty: Boolean,
onrampAvailability: Either<OnrampError, OnrampAvailability>, onrampAvailability: Either<OnrampError, OnrampAvailability>,
onPresetClick: (BigDecimal, String) -> Unit, onPresetClick: (BigDecimal, String) -> Unit,
onOtherClick: () -> Unit, onOtherClick: () -> Unit,
@ -31,10 +30,6 @@ internal class QuickTopUpBlockFactory @Inject constructor(
val amount = currencyStatus.value.amount val amount = currencyStatus.value.amount
if (amount == null || !amount.isZero()) return null if (amount == null || !amount.isZero()) return null
val isHistoryEmpty = isTxHistoryEmpty.fold(
ifLeft = { it is TxHistoryStateError.EmptyTxHistories },
ifRight = { it == 0 },
)
if (!isHistoryEmpty) return null if (!isHistoryEmpty) return null
val currency = when (val availability = onrampAvailability.getOrNull()) { val currency = when (val availability = onrampAvailability.getOrNull()) {

View file

@ -1,102 +1,75 @@
package com.tangem.feature.tokendetails.presentation.tokendetails.ui package com.tangem.feature.tokendetails.presentation.tokendetails.ui
import android.content.res.Configuration import android.content.res.Configuration
import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.border import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material3.Button import androidx.compose.foundation.layout.padding
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.BlendMode import androidx.compose.ui.graphics.BlendMode
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.util.fastForEach import androidx.compose.ui.util.fastForEach
import com.tangem.core.res.R import com.tangem.core.res.R
import com.tangem.core.ui.ds.button.PrimaryInverseTangemButton
import com.tangem.core.ui.ds.button.TangemButtonShape
import com.tangem.core.ui.ds.button.TangemButtonSize
import com.tangem.core.ui.ds.message.TangemMessageEffect
import com.tangem.core.ui.ds.message.messageEffectBackground
import com.tangem.core.ui.extensions.combinedReference import com.tangem.core.ui.extensions.combinedReference
import com.tangem.core.ui.extensions.resolveReference import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringReference import com.tangem.core.ui.extensions.stringReference
import com.tangem.utils.StringsSigns
import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreviewRedesign import com.tangem.core.ui.res.TangemThemePreviewRedesign
import com.tangem.feature.tokendetails.presentation.tokendetails.state.QuickTopUpBlockUM import com.tangem.feature.tokendetails.presentation.tokendetails.state.QuickTopUpBlockUM
import com.tangem.utils.StringsSigns
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
private val quickTopUpGradientBrush = Brush.linearGradient(
colors = listOf(Color(0xFFEDE5F3), Color(0xFFD7EDD9)),
start = Offset(0f, 0f),
end = Offset(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY),
)
private val quickTopUpBorderBrush = Brush.sweepGradient(
listOf(
Color(0x0D000000),
Color(0x26000000),
Color(0x0D000000),
Color(0x26000000),
),
)
@Composable @Composable
internal fun QuickTopUpBlock(state: QuickTopUpBlockUM, modifier: Modifier = Modifier) { internal fun QuickTopUpBlock(state: QuickTopUpBlockUM, modifier: Modifier = Modifier) {
val shape = RoundedCornerShape(TangemTheme.dimens.radius20) Box(modifier = modifier.fillMaxWidth()) {
Box(
Box( modifier = Modifier
modifier = modifier .matchParentSize()
.fillMaxWidth() .messageEffectBackground(
.clip(shape) messageEffect = TangemMessageEffect.Magic,
.background(brush = quickTopUpGradientBrush) radius = TangemTheme.dimens2.x6,
.border(width = 1.dp, brush = quickTopUpBorderBrush, shape = shape), contentColor = TangemTheme.colors2.surface.level3,
) { ),
)
Column( Column(
modifier = Modifier.padding(TangemTheme.dimens.spacing12), modifier = Modifier
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing16), .fillMaxWidth()
.padding(TangemTheme.dimens2.x3),
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x4),
) { ) {
val textColor = TangemTheme.colors.text.primary1 val titleColor = TangemTheme.colors2.text.neutral.primary
Text( Text(
text = combinedReference( text = combinedReference(
stringReference("${StringsSigns.LIGHTNING} "), stringReference("${StringsSigns.LIGHTNING} "),
resourceReference(R.string.quick_top_up_title), resourceReference(R.string.quick_top_up_title),
).resolveReference(), ).resolveReference(),
style = TangemTheme.typography.subtitle1.copy(fontWeight = FontWeight.SemiBold), style = TangemTheme.typography2.bodySemibold16,
modifier = Modifier.graphicsLayer { modifier = Modifier.graphicsLayer {
colorFilter = ColorFilter.tint(textColor, BlendMode.SrcIn) colorFilter = ColorFilter.tint(titleColor, BlendMode.SrcIn)
}, },
) )
Row( Row(
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing6), horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x1_5),
) { ) {
state.amounts.fastForEach { amountUM -> state.amounts.fastForEach { amountUM ->
Button( PrimaryInverseTangemButton(
text = amountUM.displayValue,
onClick = amountUM.onClick, onClick = amountUM.onClick,
shape = CircleShape, size = TangemButtonSize.X9,
contentPadding = PaddingValues( shape = TangemButtonShape.Rounded,
horizontal = TangemTheme.dimens.spacing12, )
vertical = TangemTheme.dimens.spacing0,
),
colors = ButtonDefaults.buttonColors(
containerColor = TangemTheme.colors.background.primary,
contentColor = TangemTheme.colors.text.primary1,
),
modifier = Modifier.heightIn(TangemTheme.dimens.size36),
elevation = null,
) {
Text(
text = amountUM.displayValue.resolveReference(),
style = TangemTheme.typography.subtitle1.copy(fontWeight = FontWeight.SemiBold),
)
}
} }
} }
} }
@ -104,6 +77,7 @@ internal fun QuickTopUpBlock(state: QuickTopUpBlockUM, modifier: Modifier = Modi
} }
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_NO) @Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_NO)
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable @Composable
private fun QuickTopUpBlock_Preview() { private fun QuickTopUpBlock_Preview() {
TangemThemePreviewRedesign { TangemThemePreviewRedesign {
@ -129,7 +103,7 @@ private fun QuickTopUpBlock_Preview() {
), ),
), ),
), ),
modifier = Modifier.padding(TangemTheme.dimens.spacing12), modifier = Modifier.padding(TangemTheme.dimens2.x3),
) )
} }
} }

View file

@ -11,7 +11,6 @@ import com.tangem.domain.onramp.model.OnrampAvailability
import com.tangem.domain.onramp.model.OnrampCountry import com.tangem.domain.onramp.model.OnrampCountry
import com.tangem.domain.onramp.model.OnrampCurrency import com.tangem.domain.onramp.model.OnrampCurrency
import com.tangem.domain.onramp.model.error.OnrampError import com.tangem.domain.onramp.model.error.OnrampError
import com.tangem.domain.txhistory.models.TxHistoryStateError
import com.tangem.features.tokendetails.TokenDetailsFeatureToggles import com.tangem.features.tokendetails.TokenDetailsFeatureToggles
import io.mockk.every import io.mockk.every
import io.mockk.mockk import io.mockk.mockk
@ -70,10 +69,6 @@ internal class QuickTopUpBlockFactoryTest {
private val notSupported: OnrampAvailability = OnrampAvailability.NotSupported(country = countryMock) private val notSupported: OnrampAvailability = OnrampAvailability.NotSupported(country = countryMock)
private val emptyHistory = TxHistoryStateError.EmptyTxHistories.left()
private val histWithItems = 5.right()
private val histRightZero = 0.right()
@Test @Test
fun `returns null when feature toggle is disabled`() { fun `returns null when feature toggle is disabled`() {
val disabledToggles: TokenDetailsFeatureToggles = mockk { val disabledToggles: TokenDetailsFeatureToggles = mockk {
@ -83,7 +78,7 @@ internal class QuickTopUpBlockFactoryTest {
val result = disabledFactory.build( val result = disabledFactory.build(
currencyStatus = zeroBalanceStatus, currencyStatus = zeroBalanceStatus,
isTxHistoryEmpty = emptyHistory, isHistoryEmpty = true,
onrampAvailability = availableUsd.right(), onrampAvailability = availableUsd.right(),
onPresetClick = { _, _ -> }, onPresetClick = { _, _ -> },
onOtherClick = {}, onOtherClick = {},
@ -96,7 +91,7 @@ internal class QuickTopUpBlockFactoryTest {
fun `returns null when balance is non-zero`() { fun `returns null when balance is non-zero`() {
val result = factory.build( val result = factory.build(
currencyStatus = nonZeroBalanceStatus, currencyStatus = nonZeroBalanceStatus,
isTxHistoryEmpty = emptyHistory, isHistoryEmpty = true,
onrampAvailability = availableUsd.right(), onrampAvailability = availableUsd.right(),
onPresetClick = { _, _ -> }, onPresetClick = { _, _ -> },
onOtherClick = {}, onOtherClick = {},
@ -106,10 +101,27 @@ internal class QuickTopUpBlockFactoryTest {
} }
@Test @Test
fun `returns null when history has transactions`() { fun `returns null when balance is loading (amount is null)`() {
val loadingStatus: CryptoCurrencyStatus = mockk {
every { value } returns CryptoCurrencyStatus.Loading
}
val result = factory.build(
currencyStatus = loadingStatus,
isHistoryEmpty = true,
onrampAvailability = availableUsd.right(),
onPresetClick = { _, _ -> },
onOtherClick = {},
)
assertThat(result).isNull()
}
@Test
fun `returns null when history is not empty`() {
val result = factory.build( val result = factory.build(
currencyStatus = zeroBalanceStatus, currencyStatus = zeroBalanceStatus,
isTxHistoryEmpty = histWithItems, isHistoryEmpty = false,
onrampAvailability = availableUsd.right(), onrampAvailability = availableUsd.right(),
onPresetClick = { _, _ -> }, onPresetClick = { _, _ -> },
onOtherClick = {}, onOtherClick = {},
@ -122,7 +134,7 @@ internal class QuickTopUpBlockFactoryTest {
fun `returns null when onramp is not available`() { fun `returns null when onramp is not available`() {
val result = factory.build( val result = factory.build(
currencyStatus = zeroBalanceStatus, currencyStatus = zeroBalanceStatus,
isTxHistoryEmpty = emptyHistory, isHistoryEmpty = true,
onrampAvailability = notSupported.right(), onrampAvailability = notSupported.right(),
onPresetClick = { _, _ -> }, onPresetClick = { _, _ -> },
onOtherClick = {}, onOtherClick = {},
@ -131,11 +143,24 @@ internal class QuickTopUpBlockFactoryTest {
assertThat(result).isNull() assertThat(result).isNull()
} }
@Test
fun `returns null when onramp availability is error`() {
val result = factory.build(
currencyStatus = zeroBalanceStatus,
isHistoryEmpty = true,
onrampAvailability = OnrampError.DataError(code = "error", description = null).left(),
onPresetClick = { _, _ -> },
onOtherClick = {},
)
assertThat(result).isNull()
}
@Test @Test
fun `returns null when currency is not USD or EUR`() { fun `returns null when currency is not USD or EUR`() {
val result = factory.build( val result = factory.build(
currencyStatus = zeroBalanceStatus, currencyStatus = zeroBalanceStatus,
isTxHistoryEmpty = emptyHistory, isHistoryEmpty = true,
onrampAvailability = OnrampAvailability.Available( onrampAvailability = OnrampAvailability.Available(
country = countryMock, country = countryMock,
currency = gbpCurrency, currency = gbpCurrency,
@ -151,7 +176,7 @@ internal class QuickTopUpBlockFactoryTest {
fun `returns block with USD presets when all conditions met`() { fun `returns block with USD presets when all conditions met`() {
val result = factory.build( val result = factory.build(
currencyStatus = zeroBalanceStatus, currencyStatus = zeroBalanceStatus,
isTxHistoryEmpty = emptyHistory, isHistoryEmpty = true,
onrampAvailability = availableUsd.right(), onrampAvailability = availableUsd.right(),
onPresetClick = { _, _ -> }, onPresetClick = { _, _ -> },
onOtherClick = {}, onOtherClick = {},
@ -178,7 +203,7 @@ internal class QuickTopUpBlockFactoryTest {
val result = factory.build( val result = factory.build(
currencyStatus = zeroBalanceStatus, currencyStatus = zeroBalanceStatus,
isTxHistoryEmpty = emptyHistory, isHistoryEmpty = true,
onrampAvailability = availableEur.right(), onrampAvailability = availableEur.right(),
onPresetClick = { _, _ -> }, onPresetClick = { _, _ -> },
onOtherClick = {}, onOtherClick = {},
@ -195,19 +220,6 @@ internal class QuickTopUpBlockFactoryTest {
assertThat(amounts.last().isOther).isTrue() assertThat(amounts.last().isOther).isTrue()
} }
@Test
fun `returns block when history count is right zero (boundary case)`() {
val result = factory.build(
currencyStatus = zeroBalanceStatus,
isTxHistoryEmpty = histRightZero,
onrampAvailability = availableUsd.right(),
onPresetClick = { _, _ -> },
onOtherClick = {},
)
assertThat(result).isNotNull()
}
@Test @Test
fun `returns block when ConfirmResidency and country supports onramp with USD`() { fun `returns block when ConfirmResidency and country supports onramp with USD`() {
val usdCountry = OnrampCountry( val usdCountry = OnrampCountry(
@ -224,7 +236,7 @@ internal class QuickTopUpBlockFactoryTest {
val result = factory.build( val result = factory.build(
currencyStatus = zeroBalanceStatus, currencyStatus = zeroBalanceStatus,
isTxHistoryEmpty = emptyHistory, isHistoryEmpty = true,
onrampAvailability = confirmResidency.right(), onrampAvailability = confirmResidency.right(),
onPresetClick = { _, _ -> }, onPresetClick = { _, _ -> },
onOtherClick = {}, onOtherClick = {},
@ -240,86 +252,6 @@ internal class QuickTopUpBlockFactoryTest {
).inOrder() ).inOrder()
} }
@Test
fun `returns null when onramp availability is error`() {
val result = factory.build(
currencyStatus = zeroBalanceStatus,
isTxHistoryEmpty = emptyHistory,
onrampAvailability = OnrampError.DataError(code = "error", description = null).left(),
onPresetClick = { _, _ -> },
onOtherClick = {},
)
assertThat(result).isNull()
}
@Test
fun `returns null when balance is loading (amount is null)`() {
val loadingStatus: CryptoCurrencyStatus = mockk {
every { value } returns CryptoCurrencyStatus.Loading
}
val result = factory.build(
currencyStatus = loadingStatus,
isTxHistoryEmpty = emptyHistory,
onrampAvailability = availableUsd.right(),
onPresetClick = { _, _ -> },
onOtherClick = {},
)
assertThat(result).isNull()
}
@Test
fun `returns null when tx history is not implemented`() {
val result = factory.build(
currencyStatus = zeroBalanceStatus,
isTxHistoryEmpty = TxHistoryStateError.TxHistoryNotImplemented.left(),
onrampAvailability = availableUsd.right(),
onPresetClick = { _, _ -> },
onOtherClick = {},
)
assertThat(result).isNull()
}
@Test
fun `returns null when tx history fetch fails with data error`() {
val result = factory.build(
currencyStatus = zeroBalanceStatus,
isTxHistoryEmpty = TxHistoryStateError.DataError(RuntimeException("network error")).left(),
onrampAvailability = availableUsd.right(),
onPresetClick = { _, _ -> },
onOtherClick = {},
)
assertThat(result).isNull()
}
@Test
fun `returns null when ConfirmResidency with non-USD or EUR default currency`() {
val gbpCountry = OnrampCountry(
id = "gb",
name = "United Kingdom",
code = "GB",
image = "",
alpha3 = "GBR",
continent = "Europe",
defaultCurrency = gbpCurrency,
onrampAvailable = true,
)
val result = factory.build(
currencyStatus = zeroBalanceStatus,
isTxHistoryEmpty = emptyHistory,
onrampAvailability = OnrampAvailability.ConfirmResidency(country = gbpCountry).right(),
onPresetClick = { _, _ -> },
onOtherClick = {},
)
assertThat(result).isNull()
}
@Test @Test
fun `returns null when ConfirmResidency but country does not support onramp`() { fun `returns null when ConfirmResidency but country does not support onramp`() {
val restrictedCountry = OnrampCountry( val restrictedCountry = OnrampCountry(
@ -336,7 +268,7 @@ internal class QuickTopUpBlockFactoryTest {
val result = factory.build( val result = factory.build(
currencyStatus = zeroBalanceStatus, currencyStatus = zeroBalanceStatus,
isTxHistoryEmpty = emptyHistory, isHistoryEmpty = true,
onrampAvailability = confirmResidency.right(), onrampAvailability = confirmResidency.right(),
onPresetClick = { _, _ -> }, onPresetClick = { _, _ -> },
onOtherClick = {}, onOtherClick = {},