Updated on 2026-08-14

This commit is contained in:
Tangem 2026-06-15 22:43:52 +03:00
commit d6f9f59866
1729 changed files with 67614 additions and 9361 deletions

View file

@ -15,8 +15,8 @@ import com.tangem.core.decompose.context.childByContext
import com.tangem.core.decompose.model.getOrCreateModel
import com.tangem.core.ui.decompose.ComposableContentComponent
import com.tangem.features.commonfeatures.api.portfolioselector.PortfolioSelectorComponent
import com.tangem.features.send.v2.api.FeeSelectorBlockComponent
import com.tangem.features.send.v2.api.FeeSelectorComponent
import com.tangem.features.send.api.FeeSelectorBlockComponent
import com.tangem.features.send.api.FeeSelectorComponent
import com.tangem.features.walletconnect.components.WcRoutingComponent
import com.tangem.features.walletconnect.connections.components.AlertsComponent
import com.tangem.features.walletconnect.connections.components.AlertsComponent.AlertType.*

View file

@ -17,8 +17,8 @@ import com.tangem.core.ui.components.audits.AuditLabelUM
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.res.TangemTheme
import com.tangem.features.send.v2.api.FeeSelectorBlockComponent
import com.tangem.features.send.v2.api.entity.FeeSelectorUM
import com.tangem.features.send.api.FeeSelectorBlockComponent
import com.tangem.features.send.api.entity.FeeSelectorUM
import com.tangem.features.walletconnect.impl.R
internal class PreviewFeeSelectorBlockComponent : FeeSelectorBlockComponent {

View file

@ -3,10 +3,10 @@ package com.tangem.features.walletconnect.transaction.components.common
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
import com.tangem.domain.walletconnect.WcAnalyticEvents
import com.tangem.features.send.v2.api.FeeSelectorComponent
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents
import com.tangem.features.send.v2.api.params.FeeSelectorParams.FeeDisplaySource
import com.tangem.features.send.v2.api.params.FeeSelectorParams.FeeSelectorDetailsParams
import com.tangem.features.send.api.FeeSelectorComponent
import com.tangem.features.send.api.analytics.CommonSendAnalyticEvents
import com.tangem.features.send.api.params.FeeSelectorParams.FeeDisplaySource
import com.tangem.features.send.api.params.FeeSelectorParams.FeeSelectorDetailsParams
import com.tangem.features.walletconnect.connections.components.AlertsComponentV2
import com.tangem.features.walletconnect.connections.utils.WcAlertsFactory.createCommonTransactionAppInfoAlertUM
import com.tangem.features.walletconnect.transaction.components.send.WcCustomAllowanceComponent

View file

@ -7,10 +7,10 @@ import com.arkivanov.essenty.lifecycle.doOnResume
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
import com.tangem.domain.walletconnect.WcAnalyticEvents
import com.tangem.features.send.v2.api.FeeSelectorBlockComponent
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents
import com.tangem.features.send.v2.api.entity.FeeSelectorUM
import com.tangem.features.send.v2.api.params.FeeSelectorParams
import com.tangem.features.send.api.FeeSelectorBlockComponent
import com.tangem.features.send.api.analytics.CommonSendAnalyticEvents
import com.tangem.features.send.api.entity.FeeSelectorUM
import com.tangem.features.send.api.params.FeeSelectorParams
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionFeeState
import com.tangem.features.walletconnect.transaction.model.WcSendTransactionModel
import com.tangem.features.walletconnect.transaction.ui.send.WcSendTransactionModalBottomSheet

View file

@ -5,8 +5,8 @@ import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.decompose.context.childByContext
import com.tangem.core.decompose.model.getOrCreateModel
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
import com.tangem.features.send.v2.api.FeeSelectorBlockComponent
import com.tangem.features.send.v2.api.FeeSelectorComponent
import com.tangem.features.send.api.FeeSelectorBlockComponent
import com.tangem.features.send.api.FeeSelectorComponent
import com.tangem.features.walletconnect.transaction.components.common.WcCommonTransactionComponentDelegate
import com.tangem.features.walletconnect.transaction.components.common.WcTransactionModelParams
import com.tangem.features.walletconnect.transaction.components.common.getWcCommonScreen

View file

@ -0,0 +1,52 @@
package com.tangem.features.walletconnect.transaction.converter
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.domain.walletconnect.model.WcBitcoinMethod
import com.tangem.features.walletconnect.impl.R
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionRequestBlockUM
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionRequestInfoItemUM
import com.tangem.utils.converter.Converter
import kotlinx.collections.immutable.toImmutableList
import javax.inject.Inject
/**
* Builds a transaction request details block (recipient and amount) for a Bitcoin `sendTransfer` WalletConnect request.
*
*/
internal class WcBtcSendTransferRequestInfoConverter @Inject constructor() :
Converter<WcBtcSendTransferRequestInfoConverter.Input, WcTransactionRequestBlockUM> {
override fun convert(value: Input): WcTransactionRequestBlockUM {
val method = value.method
return WcTransactionRequestBlockUM(
info = buildList {
add(WcTransactionRequestInfoItemUM(resourceReference(R.string.common_from), method.account))
add(WcTransactionRequestInfoItemUM(resourceReference(R.string.common_to), method.recipientAddress))
add(
WcTransactionRequestInfoItemUM(
title = resourceReference(R.string.common_amount),
description = formatAmount(method.amount, value.decimals, value.symbol),
),
)
val changeAddress = method.changeAddress
if (!changeAddress.isNullOrEmpty()) {
add(WcTransactionRequestInfoItemUM(resourceReference(R.string.wc_change_address), changeAddress))
}
}.toImmutableList(),
)
}
private fun formatAmount(amount: String, decimals: Int, symbol: String): String {
val value = amount.toBigDecimalOrNull()
?.movePointLeft(decimals)
?.stripTrailingZeros()
?: return amount
return "${value.toPlainString()} $symbol"
}
data class Input(
val method: WcBitcoinMethod.SendTransfer,
val decimals: Int,
val symbol: String,
)
}

View file

@ -6,20 +6,23 @@ import com.tangem.domain.models.wallet.isHotWallet
import com.tangem.domain.walletconnect.model.WcBitcoinMethod
import com.tangem.domain.walletconnect.model.WcEthMethod
import com.tangem.domain.walletconnect.model.WcMethod
import com.tangem.domain.walletconnect.model.WcPsbtOutput
import com.tangem.domain.walletconnect.model.WcSolanaMethod
import com.tangem.domain.walletconnect.usecase.method.BlockAidTransactionCheck
import com.tangem.domain.walletconnect.usecase.method.WcMethodContext
import com.tangem.domain.walletconnect.usecase.method.WcSignState
import com.tangem.domain.walletconnect.usecase.method.WcSignStep
import com.tangem.features.send.v2.api.entity.FeeSelectorUM
import com.tangem.features.send.api.entity.FeeSelectorUM
import com.tangem.features.walletconnect.transaction.entity.blockaid.WcSendReceiveTransactionCheckResultsUM
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionActionsUM
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionFeeState
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionRequestBlockUM
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionRequestInfoUM
import com.tangem.features.walletconnect.transaction.entity.send.WcSendTransactionItemUM
import com.tangem.features.walletconnect.transaction.entity.send.WcSendTransactionUM
import com.tangem.features.walletconnect.utils.WcNotificationsFactory
import com.tangem.utils.converter.Converter
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList
import javax.inject.Inject
@ -27,6 +30,8 @@ internal class WcSendTransactionUMConverter @Inject constructor(
private val appInfoContentUMConverter: WcTransactionAppInfoContentUMConverter,
private val networkInfoUMConverter: WcNetworkInfoUMConverter,
private val requestBlockUMConverter: WcTransactionRequestBlockUMConverter,
private val btcSendTransferRequestInfoConverter: WcBtcSendTransferRequestInfoConverter,
private val signPsbtRequestInfoConverter: WcSignPsbtRequestInfoConverter,
private val notificationsFactory: WcNotificationsFactory,
) : Converter<WcSendTransactionUMConverter.Input, WcSendTransactionUM?> {
@ -76,13 +81,7 @@ internal class WcSendTransactionUMConverter @Inject constructor(
is WcTransactionFeeState.Success -> value.feeSelectorUM ?: FeeSelectorUM.Loading
},
transactionRequestInfo = WcTransactionRequestInfoUM(
blocks = buildList {
addAll(
requestBlockUMConverter.convert(
WcTransactionRequestBlockUMConverter.Input(value.context.rawSdkRequest),
),
)
}.toImmutableList(),
blocks = buildRequestInfoBlocks(value),
onCopy = value.actions.onCopy,
),
)
@ -97,6 +96,37 @@ internal class WcSendTransactionUMConverter @Inject constructor(
}
}
private fun buildRequestInfoBlocks(value: Input): ImmutableList<WcTransactionRequestBlockUM> = buildList {
addAll(
requestBlockUMConverter.convert(
WcTransactionRequestBlockUMConverter.Input(value.context.rawSdkRequest),
),
)
val method = value.context.method
if (method is WcBitcoinMethod.SendTransfer) {
add(
btcSendTransferRequestInfoConverter.convert(
WcBtcSendTransferRequestInfoConverter.Input(
method = method,
decimals = value.cryptoCurrencyStatus.currency.decimals,
symbol = value.cryptoCurrencyStatus.currency.symbol,
),
),
)
}
if (method is WcBitcoinMethod.SignPsbt && value.psbtOutputs != null) {
addAll(
signPsbtRequestInfoConverter.convert(
WcSignPsbtRequestInfoConverter.Input(
outputs = value.psbtOutputs,
decimals = value.cryptoCurrencyStatus.currency.decimals,
symbol = value.cryptoCurrencyStatus.currency.symbol,
),
),
)
}
}.toImmutableList()
data class Input(
val context: WcMethodContext,
val portfolioName: AccountTitleUM?,
@ -106,6 +136,7 @@ internal class WcSendTransactionUMConverter @Inject constructor(
val feeSelectorUM: FeeSelectorUM?,
val cryptoCurrencyStatus: CryptoCurrencyStatus,
val securityCheck: BlockAidTransactionCheck.Result?,
val psbtOutputs: List<WcPsbtOutput>?,
val onFeeReload: () -> Unit,
)
}

View file

@ -0,0 +1,66 @@
package com.tangem.features.walletconnect.transaction.converter
import com.tangem.core.ui.extensions.combinedReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.domain.walletconnect.model.WcPsbtOutput
import com.tangem.features.walletconnect.impl.R
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionRequestBlockUM
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionRequestInfoItemUM
import com.tangem.utils.converter.Converter
import kotlinx.collections.immutable.toImmutableList
import java.math.BigDecimal
import javax.inject.Inject
/**
* Builds transaction request details blocks (recipient + amount per output) for a Bitcoin `signPsbt` request.
*
*/
internal class WcSignPsbtRequestInfoConverter @Inject constructor() :
Converter<WcSignPsbtRequestInfoConverter.Input, List<WcTransactionRequestBlockUM>> {
override fun convert(value: Input): List<WcTransactionRequestBlockUM> {
val outputs = value.outputs
if (outputs.isEmpty()) return emptyList()
val shouldShowIndex = outputs.size > 1
return outputs.mapIndexed { index, output ->
val recipientTitle = when {
output.address == null -> resourceReference(R.string.common_no_address)
shouldShowIndex -> combinedReference(
resourceReference(R.string.common_to),
stringReference(" ${index + 1}"),
)
else -> resourceReference(R.string.common_to)
}
WcTransactionRequestBlockUM(
info = buildList {
add(
WcTransactionRequestInfoItemUM(
title = recipientTitle,
description = output.address.orEmpty(),
),
)
add(
WcTransactionRequestInfoItemUM(
title = resourceReference(R.string.common_amount),
description = formatAmount(output.amountSatoshi, value.decimals, value.symbol),
),
)
}.toImmutableList(),
)
}
}
private fun formatAmount(amountSatoshi: Long, decimals: Int, symbol: String): String {
val value = BigDecimal.valueOf(amountSatoshi)
.movePointLeft(decimals)
.stripTrailingZeros()
return "${value.toPlainString()} $symbol"
}
data class Input(
val outputs: List<WcPsbtOutput>,
val decimals: Int,
val symbol: String,
)
}

View file

@ -4,7 +4,7 @@ import com.domain.blockaid.models.transaction.ValidationResult
import com.tangem.common.ui.account.AccountTitleUM
import com.tangem.common.ui.notifications.NotificationUM
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
import com.tangem.features.send.v2.api.entity.FeeSelectorUM
import com.tangem.features.send.api.entity.FeeSelectorUM
import com.tangem.features.walletconnect.transaction.entity.approve.WcSpendAllowanceUM
import com.tangem.features.walletconnect.transaction.entity.blockaid.WcSendReceiveTransactionCheckResultsUM
import com.tangem.features.walletconnect.transaction.entity.common.WcCommonTransactionUM

View file

@ -40,14 +40,15 @@ import com.tangem.domain.walletconnect.WcAnalyticEvents
import com.tangem.domain.walletconnect.WcAnalyticEvents.SignatureRequestReceived.EmulationStatus
import com.tangem.domain.walletconnect.WcAnalyticEvents.SolanaLargeTransaction
import com.tangem.domain.walletconnect.WcRequestUseCaseFactory
import com.tangem.domain.walletconnect.model.WcPsbtOutput
import com.tangem.domain.walletconnect.model.WcRequestError
import com.tangem.domain.walletconnect.model.WcRequestError.Companion.message
import com.tangem.domain.walletconnect.usecase.method.*
import com.tangem.features.send.v2.api.callbacks.FeeSelectorModelCallback
import com.tangem.features.send.v2.api.entity.FeeSelectorUM
import com.tangem.features.send.v2.api.params.FeeSelectorParams.FeeStateConfiguration
import com.tangem.features.send.v2.api.subcomponents.feeSelector.FeeSelectorReloadTrigger
import com.tangem.features.send.v2.api.subcomponents.feeSelector.entity.FeeSelectorData
import com.tangem.features.send.api.callbacks.FeeSelectorModelCallback
import com.tangem.features.send.api.entity.FeeSelectorUM
import com.tangem.features.send.api.params.FeeSelectorParams.FeeStateConfiguration
import com.tangem.features.send.api.subcomponents.feeSelector.FeeSelectorReloadTrigger
import com.tangem.features.send.api.subcomponents.feeSelector.entity.FeeSelectorData
import com.tangem.features.walletconnect.connections.routing.WcInnerRoute
import com.tangem.features.walletconnect.impl.R
import com.tangem.features.walletconnect.transaction.components.common.WcTransactionModelParams
@ -103,6 +104,7 @@ internal class WcSendTransactionModel @Inject constructor(
private var useCase: WcSignUseCase<*> by Delegates.notNull()
private var signState: WcSignState<*> by Delegates.notNull()
private var wcApproval: WcApproval? = null
private var psbtOutputs: List<WcPsbtOutput>? = null
private var sign: () -> Unit = {}
private val blockAidUiConverter = WcSendAndReceiveBlockAidUiConverter()
private val feeReloadState = MutableStateFlow(false)
@ -129,6 +131,9 @@ internal class WcSendTransactionModel @Inject constructor(
.onNone { unknownMethodRunnable() }
.getOrNull() ?: return@launch
this@WcSendTransactionModel.useCase = useCase
if (useCase is WcPsbtUseCase) {
psbtOutputs = useCase.parsePsbtOutputs()
}
(useCase as? WcMutableFee)
?.dAppFee()
?.let { dAppFee ->
@ -292,6 +297,7 @@ internal class WcSendTransactionModel @Inject constructor(
cryptoCurrencyStatus = cryptoCurrencyStatus,
onFeeReload = ::triggerFeeReload,
securityCheck = securityCheck.getOrNull(),
psbtOutputs = psbtOutputs,
portfolioName = portfolioNameDelegate.createAccountTitleUM(useCase.session),
),
)

View file

@ -15,8 +15,8 @@ import com.tangem.common.ui.account.AccountTitleUM
import com.tangem.core.ui.components.divider.DividerWithPadding
import com.tangem.core.ui.extensions.clickableSingle
import com.tangem.core.ui.res.TangemTheme
import com.tangem.features.send.v2.api.FeeSelectorBlockComponent
import com.tangem.features.send.v2.api.entity.FeeSelectorUM
import com.tangem.features.send.api.FeeSelectorBlockComponent
import com.tangem.features.send.api.entity.FeeSelectorUM
import com.tangem.features.walletconnect.transaction.entity.common.WcNetworkInfoUM
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionFeeState

View file

@ -31,8 +31,8 @@ import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.features.send.v2.api.FeeSelectorBlockComponent
import com.tangem.features.send.v2.api.entity.FeeSelectorUM
import com.tangem.features.send.api.FeeSelectorBlockComponent
import com.tangem.features.send.api.entity.FeeSelectorUM
import com.tangem.features.walletconnect.connections.entity.VerifiedDAppState
import com.tangem.features.walletconnect.connections.ui.WcAppInfoItem
import com.tangem.features.walletconnect.impl.R

View file

@ -5,8 +5,8 @@ import com.tangem.core.ui.components.notifications.NotificationConfig
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.wrappedList
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.features.send.v2.api.entity.FeeSelectorUM
import com.tangem.features.send.v2.api.subcomponents.feeSelector.utils.FeeCalculationUtils
import com.tangem.features.send.api.entity.FeeSelectorUM
import com.tangem.features.send.api.subcomponents.feeSelector.utils.FeeCalculationUtils
import com.tangem.features.walletconnect.impl.R
import javax.inject.Inject

View file

@ -5,7 +5,7 @@ import com.tangem.core.ui.extensions.TextReference
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionRequestBlockUM
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionRequestInfoItemUM
import kotlinx.collections.immutable.toImmutableList
import org.junit.Test
import org.junit.jupiter.api.Test
class TransactionParamsConverterTest {

View file

@ -0,0 +1,106 @@
package com.tangem.features.walletconnect.transaction.converter
import com.google.common.truth.Truth
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.domain.walletconnect.model.WcBitcoinMethod
import com.tangem.features.walletconnect.impl.R
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionRequestBlockUM
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionRequestInfoItemUM
import kotlinx.collections.immutable.toImmutableList
import org.junit.jupiter.api.Test
class WcBtcSendTransferRequestInfoConverterTest {
private val converter = WcBtcSendTransferRequestInfoConverter()
@Test
fun `GIVEN sendTransfer with change address WHEN convert THEN block with from to amount and change`() {
val input = WcBtcSendTransferRequestInfoConverter.Input(
method = WcBitcoinMethod.SendTransfer(
account = "bc1qsenderaddress",
recipientAddress = "bc1qrecipientaddress",
amount = "5000000",
memo = null,
changeAddress = "bc1qchangeaddress",
),
decimals = 8,
symbol = "BTC",
)
val expected = WcTransactionRequestBlockUM(
info = listOf(
WcTransactionRequestInfoItemUM(resourceReference(R.string.common_from), "bc1qsenderaddress"),
WcTransactionRequestInfoItemUM(resourceReference(R.string.common_to), "bc1qrecipientaddress"),
WcTransactionRequestInfoItemUM(resourceReference(R.string.common_amount), "0.05 BTC"),
WcTransactionRequestInfoItemUM(resourceReference(R.string.wc_change_address), "bc1qchangeaddress"),
).toImmutableList(),
)
Truth.assertThat(converter.convert(input)).isEqualTo(expected)
}
@Test
fun `GIVEN sendTransfer without change address WHEN convert THEN block with from to amount only`() {
val input = WcBtcSendTransferRequestInfoConverter.Input(
method = WcBitcoinMethod.SendTransfer(
account = "bc1qsenderaddress",
recipientAddress = "bc1qrecipientaddress",
amount = "100000000",
memo = null,
changeAddress = null,
),
decimals = 8,
symbol = "BTC",
)
val expected = WcTransactionRequestBlockUM(
info = listOf(
WcTransactionRequestInfoItemUM(resourceReference(R.string.common_from), "bc1qsenderaddress"),
WcTransactionRequestInfoItemUM(resourceReference(R.string.common_to), "bc1qrecipientaddress"),
WcTransactionRequestInfoItemUM(resourceReference(R.string.common_amount), "1 BTC"),
).toImmutableList(),
)
Truth.assertThat(converter.convert(input)).isEqualTo(expected)
}
@Test
fun `GIVEN blank change address WHEN convert THEN change address item is omitted`() {
val input = WcBtcSendTransferRequestInfoConverter.Input(
method = WcBitcoinMethod.SendTransfer(
account = "bc1qsenderaddress",
recipientAddress = "bc1qrecipientaddress",
amount = "1",
memo = null,
changeAddress = "",
),
decimals = 8,
symbol = "BTC",
)
val result = converter.convert(input)
Truth.assertThat(result.info).hasSize(3)
Truth.assertThat(result.info.last().title).isEqualTo(resourceReference(R.string.common_amount))
}
@Test
fun `GIVEN non-numeric amount WHEN convert THEN raw amount is shown`() {
val input = WcBtcSendTransferRequestInfoConverter.Input(
method = WcBitcoinMethod.SendTransfer(
account = "bc1qsenderaddress",
recipientAddress = "bc1qrecipientaddress",
amount = "not-a-number",
memo = null,
changeAddress = null,
),
decimals = 8,
symbol = "BTC",
)
val amountItem = converter.convert(input).info[2]
Truth.assertThat(amountItem.title).isEqualTo(resourceReference(R.string.common_amount))
Truth.assertThat(amountItem.description).isEqualTo("not-a-number")
}
}

View file

@ -0,0 +1,82 @@
package com.tangem.features.walletconnect.transaction.converter
import com.google.common.truth.Truth
import com.tangem.core.ui.extensions.combinedReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.domain.walletconnect.model.WcPsbtOutput
import com.tangem.features.walletconnect.impl.R
import org.junit.jupiter.api.Test
class WcSignPsbtRequestInfoConverterTest {
private val converter = WcSignPsbtRequestInfoConverter()
@Test
fun `GIVEN single output WHEN convert THEN one block with to and amount`() {
val input = WcSignPsbtRequestInfoConverter.Input(
outputs = listOf(WcPsbtOutput(address = "bc1qrecipient", amountSatoshi = 100_000L)),
decimals = 8,
symbol = "BTC",
)
val result = converter.convert(input)
Truth.assertThat(result).hasSize(1)
Truth.assertThat(result[0].info.map { it.title }).containsExactly(
resourceReference(R.string.common_to),
resourceReference(R.string.common_amount),
).inOrder()
Truth.assertThat(result[0].info[0].description).isEqualTo("bc1qrecipient")
Truth.assertThat(result[0].info[1].description).isEqualTo("0.001 BTC")
}
@Test
fun `GIVEN multiple outputs WHEN convert THEN indexed blocks per output`() {
val input = WcSignPsbtRequestInfoConverter.Input(
outputs = listOf(
WcPsbtOutput(address = "bc1qfirst", amountSatoshi = 250_000L),
WcPsbtOutput(address = "bc1qsecond", amountSatoshi = 1_0000_0000L),
),
decimals = 8,
symbol = "BTC",
)
val result = converter.convert(input)
Truth.assertThat(result).hasSize(2)
Truth.assertThat(result[0].info[0].title)
.isEqualTo(combinedReference(resourceReference(R.string.common_to), stringReference(" 1")))
Truth.assertThat(result[0].info[1].description).isEqualTo("0.0025 BTC")
Truth.assertThat(result[1].info[0].title)
.isEqualTo(combinedReference(resourceReference(R.string.common_to), stringReference(" 2")))
Truth.assertThat(result[1].info[0].description).isEqualTo("bc1qsecond")
Truth.assertThat(result[1].info[1].description).isEqualTo("1 BTC")
}
@Test
fun `GIVEN output with undecodable address WHEN convert THEN no address title and empty recipient`() {
val input = WcSignPsbtRequestInfoConverter.Input(
outputs = listOf(WcPsbtOutput(address = null, amountSatoshi = 50_000L)),
decimals = 8,
symbol = "BTC",
)
val result = converter.convert(input)
Truth.assertThat(result[0].info[0].title).isEqualTo(resourceReference(R.string.common_no_address))
Truth.assertThat(result[0].info[0].description).isEqualTo("")
Truth.assertThat(result[0].info[1].description).isEqualTo("0.0005 BTC")
}
@Test
fun `GIVEN no outputs WHEN convert THEN empty list`() {
val input = WcSignPsbtRequestInfoConverter.Input(
outputs = emptyList(),
decimals = 8,
symbol = "BTC",
)
Truth.assertThat(converter.convert(input)).isEmpty()
}
}