Updated on 2026-08-14
This commit is contained in:
parent
158fd355de
commit
473aeee675
18 changed files with 1176 additions and 226 deletions
|
|
@ -267,29 +267,45 @@ internal class SendModel @Inject constructor(
|
|||
private suspend fun prepareTransferTransaction(): Either<Throwable, TransactionData> {
|
||||
val predefinedValues = predefinedValues
|
||||
val cryptoCurrencyStatus = cryptoCurrencyStatusFlow.value
|
||||
return if (predefinedValues is PredefinedValues.Content.Deeplink) {
|
||||
val predefinedAmount = predefinedValues.amount.parseBigDecimalOrNull()
|
||||
createTransferTransactionUseCase(
|
||||
amount = predefinedAmount?.convertToSdkAmount(cryptoCurrencyStatus) ?: error("Invalid amount"),
|
||||
memo = predefinedValues.memo,
|
||||
destination = predefinedValues.address,
|
||||
userWalletId = userWallet.walletId,
|
||||
network = cryptoCurrency.network,
|
||||
)
|
||||
} else {
|
||||
val destinationUM = uiState.value.destinationUM as? DestinationUM.Content ?: error("Invalid destination")
|
||||
val amountUM = uiState.value.amountUM as? AmountState.Data ?: error("Invalid amount")
|
||||
val enteredDestinationAddress = destinationUM.addressTextField.actualAddress
|
||||
val enteredMemo = destinationUM.memoTextField?.value
|
||||
val enteredAmount = amountUM.amountTextField.cryptoAmount.value ?: error("Invalid amount")
|
||||
return when (predefinedValues) {
|
||||
is PredefinedValues.Content.Deeplink -> {
|
||||
val predefinedAmount = predefinedValues.amount.parseBigDecimalOrNull()
|
||||
createTransferTransactionUseCase(
|
||||
amount = predefinedAmount?.convertToSdkAmount(cryptoCurrencyStatus)
|
||||
?: error("Invalid amount"),
|
||||
memo = predefinedValues.memo,
|
||||
destination = predefinedValues.address,
|
||||
userWalletId = userWallet.walletId,
|
||||
network = cryptoCurrency.network,
|
||||
)
|
||||
}
|
||||
is PredefinedValues.Content.QrCode -> {
|
||||
val predefinedAmount = predefinedValues.amount?.parseBigDecimalOrNull()
|
||||
createTransferTransactionUseCase(
|
||||
amount = predefinedAmount?.convertToSdkAmount(cryptoCurrencyStatus)
|
||||
?: error("Invalid amount"),
|
||||
memo = predefinedValues.memo,
|
||||
destination = predefinedValues.address,
|
||||
userWalletId = userWallet.walletId,
|
||||
network = cryptoCurrency.network,
|
||||
)
|
||||
}
|
||||
PredefinedValues.Empty -> {
|
||||
val destinationUM = uiState.value.destinationUM as? DestinationUM.Content
|
||||
?: error("Invalid destination")
|
||||
val amountUM = uiState.value.amountUM as? AmountState.Data ?: error("Invalid amount")
|
||||
val enteredDestinationAddress = destinationUM.addressTextField.actualAddress
|
||||
val enteredMemo = destinationUM.memoTextField?.value
|
||||
val enteredAmount = amountUM.amountTextField.cryptoAmount.value ?: error("Invalid amount")
|
||||
|
||||
createTransferTransactionUseCase(
|
||||
amount = enteredAmount.convertToSdkAmount(cryptoCurrencyStatus),
|
||||
memo = enteredMemo,
|
||||
destination = enteredDestinationAddress,
|
||||
userWalletId = userWallet.walletId,
|
||||
network = cryptoCurrency.network,
|
||||
)
|
||||
createTransferTransactionUseCase(
|
||||
amount = enteredAmount.convertToSdkAmount(cryptoCurrencyStatus),
|
||||
memo = enteredMemo,
|
||||
destination = enteredDestinationAddress,
|
||||
userWalletId = userWallet.walletId,
|
||||
network = cryptoCurrency.network,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -348,6 +364,12 @@ internal class SendModel @Inject constructor(
|
|||
memo = params.tag,
|
||||
transactionId = predefinedTxId,
|
||||
)
|
||||
} else if (predefinedAddress != null) {
|
||||
PredefinedValues.Content.QrCode(
|
||||
amount = predefinedAmount,
|
||||
address = predefinedAddress,
|
||||
memo = params.tag,
|
||||
)
|
||||
} else {
|
||||
PredefinedValues.Empty
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ internal class SendDestinationModel @Inject constructor(
|
|||
),
|
||||
)
|
||||
val params = params as? DestinationBlockParams
|
||||
val predefinedValues = params?.predefinedValues as? PredefinedValues.Content.Deeplink
|
||||
val predefinedValues = params?.predefinedValues as? PredefinedValues.Content
|
||||
if (predefinedValues?.address != null) {
|
||||
_uiState.update(
|
||||
SendDestinationPredefinedStateTransformer(
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import arrow.core.getOrElse
|
|||
import com.arkivanov.decompose.router.slot.activate
|
||||
import com.arkivanov.decompose.router.slot.dismiss
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.core.ui.utils.parseBigDecimal
|
||||
import com.tangem.core.analytics.models.AnalyticsParam
|
||||
import com.tangem.core.analytics.models.event.MainScreenAnalyticsEvent
|
||||
import com.tangem.core.analytics.utils.TrackingContextProxy
|
||||
|
|
@ -25,13 +26,12 @@ import com.tangem.domain.notifications.repository.NotificationsRepository
|
|||
import com.tangem.domain.qrscanning.models.QrResultSource
|
||||
import com.tangem.domain.qrscanning.models.SourceType
|
||||
import com.tangem.domain.qrscanning.usecases.ListenToQrScanningUseCase
|
||||
import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesProducer
|
||||
import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesSupplier
|
||||
import com.tangem.domain.qrscanning.models.QrSendTarget
|
||||
import com.tangem.domain.walletconnect.WcPairService
|
||||
import com.tangem.domain.walletconnect.model.WcPairRequest
|
||||
import com.tangem.domain.pay.repository.OnboardingRepository
|
||||
import com.tangem.domain.pay.usecase.TangemPayMainScreenCustomerInfoUseCase
|
||||
import com.tangem.domain.qrscanning.usecases.ClassifyQrCodeUseCase
|
||||
import com.tangem.domain.qrscanning.usecases.ResolveQrSendTargetsUseCase
|
||||
import com.tangem.domain.settings.*
|
||||
import com.tangem.domain.tokens.RefreshMultiCurrencyWalletQuotesUseCase
|
||||
import com.tangem.domain.wallets.usecase.*
|
||||
|
|
@ -40,7 +40,6 @@ import com.tangem.domain.yield.supply.usecase.YieldSupplyApyUpdateUseCase
|
|||
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
|
||||
import com.tangem.feature.wallet.presentation.router.InnerWalletRouter
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.WalletScreenAnalyticsEvent
|
||||
import com.tangem.domain.qrscanning.models.ClassifiedQrContent
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.utils.SelectedWalletAnalyticsSender
|
||||
import com.tangem.feature.wallet.presentation.wallet.domain.OnrampStatusFactory
|
||||
import com.tangem.feature.wallet.presentation.wallet.domain.WalletContentFetcher
|
||||
|
|
@ -115,8 +114,7 @@ internal class WalletModel @Inject constructor(
|
|||
private val walletFeatureToggles: WalletFeatureToggles,
|
||||
private val listenToQrScanningUseCase: ListenToQrScanningUseCase,
|
||||
private val wcPairService: WcPairService,
|
||||
private val multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier,
|
||||
private val classifyQrCodeUseCase: ClassifyQrCodeUseCase,
|
||||
private val resolveQrSendTargetsUseCase: ResolveQrSendTargetsUseCase,
|
||||
val screenLifecycleProvider: ScreenLifecycleProvider,
|
||||
val innerWalletRouter: InnerWalletRouter,
|
||||
) : Model() {
|
||||
|
|
@ -752,16 +750,8 @@ internal class WalletModel @Inject constructor(
|
|||
}
|
||||
|
||||
private suspend fun handleQrResult(qrCode: String, resultSource: QrResultSource) {
|
||||
val userWalletId = stateHolder.getSelectedWalletId()
|
||||
|
||||
val currencies = multiWalletCryptoCurrenciesSupplier
|
||||
.getSyncOrNull(MultiWalletCryptoCurrenciesProducer.Params(userWalletId))
|
||||
?.toList()
|
||||
.orEmpty()
|
||||
val classified = classifyQrCodeUseCase(qrCode, currencies)
|
||||
|
||||
when (classified) {
|
||||
is ClassifiedQrContent.WalletConnect -> {
|
||||
when (val target = resolveQrSendTargetsUseCase(qrCode)) {
|
||||
is QrSendTarget.WalletConnect -> {
|
||||
val source = when (resultSource) {
|
||||
QrResultSource.CLIPBOARD -> WcPairRequest.Source.CLIPBOARD
|
||||
QrResultSource.CAMERA,
|
||||
|
|
@ -770,34 +760,25 @@ internal class WalletModel @Inject constructor(
|
|||
}
|
||||
wcPairService.pair(
|
||||
WcPairRequest(
|
||||
userWalletId = userWalletId,
|
||||
uri = classified.uri,
|
||||
userWalletId = stateHolder.getSelectedWalletId(),
|
||||
uri = target.uri,
|
||||
source = source,
|
||||
),
|
||||
)
|
||||
}
|
||||
is ClassifiedQrContent.PaymentUri -> {
|
||||
is QrSendTarget.Single -> {
|
||||
innerWalletRouter.openSend(
|
||||
userWalletId = userWalletId,
|
||||
currency = classified.currency,
|
||||
address = classified.address,
|
||||
amount = classified.amount?.toPlainString(),
|
||||
tag = classified.memo,
|
||||
userWalletId = target.userWalletId,
|
||||
currency = target.currency,
|
||||
address = target.address,
|
||||
amount = target.amount?.parseBigDecimal(target.currency.decimals),
|
||||
tag = target.memo,
|
||||
)
|
||||
}
|
||||
is ClassifiedQrContent.PlainAddress -> {
|
||||
if (classified.matchingCurrencies.size == 1) {
|
||||
innerWalletRouter.openSend(
|
||||
userWalletId = userWalletId,
|
||||
currency = classified.matchingCurrencies.first(),
|
||||
address = classified.address,
|
||||
amount = null,
|
||||
tag = null,
|
||||
)
|
||||
}
|
||||
// TODO: [REDACTED_TASK_KEY] Network selection bottom sheet for multiple network matches
|
||||
is QrSendTarget.Multiple -> {
|
||||
// TODO: [REDACTED_TASK_KEY] Bottom sheet: Wallets (dropdown) → Accounts → Tokens
|
||||
}
|
||||
is ClassifiedQrContent.Unknown -> {
|
||||
is QrSendTarget.Unknown -> {
|
||||
// TODO: [REDACTED_TASK_KEY] Error handling for unsupported and invalid QR codes
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue