Updated on 2026-08-14
This commit is contained in:
parent
c04036723e
commit
4dc5d045a2
12 changed files with 225 additions and 106 deletions
|
|
@ -76,6 +76,7 @@ dependencies {
|
||||||
implementation(projects.data.txhistory)
|
implementation(projects.data.txhistory)
|
||||||
implementation(projects.data.wallets)
|
implementation(projects.data.wallets)
|
||||||
implementation(projects.data.analytics)
|
implementation(projects.data.analytics)
|
||||||
|
implementation(projects.data.transaction)
|
||||||
|
|
||||||
/** Features */
|
/** Features */
|
||||||
implementation(projects.features.onboarding)
|
implementation(projects.features.onboarding)
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ package com.tangem.tap.di.domain
|
||||||
|
|
||||||
import com.tangem.domain.card.repository.CardSdkConfigRepository
|
import com.tangem.domain.card.repository.CardSdkConfigRepository
|
||||||
import com.tangem.domain.demo.IsDemoCardUseCase
|
import com.tangem.domain.demo.IsDemoCardUseCase
|
||||||
|
import com.tangem.domain.transaction.TransactionRepository
|
||||||
|
import com.tangem.domain.transaction.usecase.CreateTransactionUseCase
|
||||||
import com.tangem.domain.transaction.usecase.GetFeeUseCase
|
import com.tangem.domain.transaction.usecase.GetFeeUseCase
|
||||||
import com.tangem.domain.transaction.usecase.SendTransactionUseCase
|
import com.tangem.domain.transaction.usecase.SendTransactionUseCase
|
||||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||||
|
|
@ -38,4 +40,10 @@ internal object TransactionDomainModule {
|
||||||
walletManagersFacade = walletManagersFacade,
|
walletManagersFacade = walletManagersFacade,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@ViewModelScoped
|
||||||
|
fun provideCreateTransactionUseCase(transactionRepository: TransactionRepository): CreateTransactionUseCase {
|
||||||
|
return CreateTransactionUseCase(transactionRepository)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
1
data/transaction/.gitignore
vendored
Normal file
1
data/transaction/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
/build
|
||||||
30
data/transaction/build.gradle.kts
Normal file
30
data/transaction/build.gradle.kts
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
plugins {
|
||||||
|
alias(deps.plugins.android.library)
|
||||||
|
alias(deps.plugins.kotlin.android)
|
||||||
|
alias(deps.plugins.kotlin.kapt)
|
||||||
|
alias(deps.plugins.hilt.android)
|
||||||
|
id("configuration")
|
||||||
|
}
|
||||||
|
|
||||||
|
android {
|
||||||
|
namespace = "com.tangem.data.transaction"
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
|
||||||
|
/** Tangem SDKs */
|
||||||
|
implementation(deps.tangem.blockchain)
|
||||||
|
|
||||||
|
/** Core */
|
||||||
|
implementation(projects.core.utils)
|
||||||
|
|
||||||
|
/** Domain */
|
||||||
|
implementation(projects.domain.transaction)
|
||||||
|
implementation(projects.domain.legacy)
|
||||||
|
implementation(projects.domain.wallets.models)
|
||||||
|
implementation(projects.domain.tokens.models)
|
||||||
|
|
||||||
|
/** DI */
|
||||||
|
implementation(deps.hilt.android)
|
||||||
|
kapt(deps.hilt.kapt)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,65 @@
|
||||||
|
package com.tangem.data.transaction
|
||||||
|
|
||||||
|
import androidx.core.text.isDigitsOnly
|
||||||
|
import com.tangem.blockchain.blockchains.binance.BinanceTransactionExtras
|
||||||
|
import com.tangem.blockchain.blockchains.cosmos.CosmosTransactionExtras
|
||||||
|
import com.tangem.blockchain.blockchains.stellar.StellarMemo
|
||||||
|
import com.tangem.blockchain.blockchains.stellar.StellarTransactionExtras
|
||||||
|
import com.tangem.blockchain.blockchains.ton.TonTransactionExtras
|
||||||
|
import com.tangem.blockchain.blockchains.xrp.XrpTransactionBuilder
|
||||||
|
import com.tangem.blockchain.common.Amount
|
||||||
|
import com.tangem.blockchain.common.Blockchain
|
||||||
|
import com.tangem.blockchain.common.TransactionData
|
||||||
|
import com.tangem.blockchain.common.TransactionExtras
|
||||||
|
import com.tangem.blockchain.common.transaction.Fee
|
||||||
|
import com.tangem.domain.tokens.model.Network
|
||||||
|
import com.tangem.domain.transaction.TransactionRepository
|
||||||
|
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||||
|
import com.tangem.domain.wallets.models.UserWalletId
|
||||||
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
|
internal class DefaultTransactionRepository(
|
||||||
|
private val walletManagersFacade: WalletManagersFacade,
|
||||||
|
private val coroutineDispatcherProvider: CoroutineDispatcherProvider,
|
||||||
|
) : TransactionRepository {
|
||||||
|
|
||||||
|
override suspend fun createTransaction(
|
||||||
|
amount: Amount,
|
||||||
|
fee: Fee,
|
||||||
|
memo: String?,
|
||||||
|
destination: String,
|
||||||
|
userWalletId: UserWalletId,
|
||||||
|
network: Network,
|
||||||
|
): TransactionData? = withContext(coroutineDispatcherProvider.io) {
|
||||||
|
val blockchain = Blockchain.fromId(network.id.value)
|
||||||
|
val walletManager = walletManagersFacade.getOrCreateWalletManager(
|
||||||
|
userWalletId = userWalletId,
|
||||||
|
blockchain = blockchain,
|
||||||
|
derivationPath = network.derivationPath.value,
|
||||||
|
)
|
||||||
|
|
||||||
|
return@withContext walletManager?.createTransaction(amount, fee, destination)?.copy(
|
||||||
|
extras = getMemoExtras(network.id.value, memo),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getMemoExtras(networkId: String, memo: String?): TransactionExtras? {
|
||||||
|
val blockchain = Blockchain.fromId(networkId)
|
||||||
|
if (memo == null) return null
|
||||||
|
return when (blockchain) {
|
||||||
|
Blockchain.Stellar -> {
|
||||||
|
val xmlMemo = when {
|
||||||
|
memo.isNotEmpty() && memo.isDigitsOnly() -> StellarMemo.Id(memo.toBigInteger())
|
||||||
|
else -> StellarMemo.Text(memo)
|
||||||
|
}
|
||||||
|
StellarTransactionExtras(xmlMemo)
|
||||||
|
}
|
||||||
|
Blockchain.Binance -> BinanceTransactionExtras(memo)
|
||||||
|
Blockchain.XRP -> memo.toLongOrNull()?.let { XrpTransactionBuilder.XrpTransactionExtras(it) }
|
||||||
|
Blockchain.Cosmos -> CosmosTransactionExtras(memo)
|
||||||
|
Blockchain.TON -> TonTransactionExtras(memo)
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
package com.tangem.data.transaction.di
|
||||||
|
|
||||||
|
import com.tangem.data.transaction.DefaultTransactionRepository
|
||||||
|
import com.tangem.domain.transaction.TransactionRepository
|
||||||
|
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||||
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
|
import dagger.Module
|
||||||
|
import dagger.Provides
|
||||||
|
import dagger.hilt.InstallIn
|
||||||
|
import dagger.hilt.components.SingletonComponent
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Module
|
||||||
|
@InstallIn(SingletonComponent::class)
|
||||||
|
internal object TransactionDataModule {
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
fun providesTransactionRepository(
|
||||||
|
walletManagersFacade: WalletManagersFacade,
|
||||||
|
coroutineDispatcherProvider: CoroutineDispatcherProvider,
|
||||||
|
): TransactionRepository {
|
||||||
|
return DefaultTransactionRepository(
|
||||||
|
walletManagersFacade = walletManagersFacade,
|
||||||
|
coroutineDispatcherProvider = coroutineDispatcherProvider,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
package com.tangem.domain.transaction
|
||||||
|
|
||||||
|
import com.tangem.blockchain.common.Amount
|
||||||
|
import com.tangem.blockchain.common.TransactionData
|
||||||
|
import com.tangem.blockchain.common.transaction.Fee
|
||||||
|
import com.tangem.domain.tokens.model.Network
|
||||||
|
import com.tangem.domain.wallets.models.UserWalletId
|
||||||
|
|
||||||
|
interface TransactionRepository {
|
||||||
|
|
||||||
|
@Suppress("LongParameterList")
|
||||||
|
suspend fun createTransaction(
|
||||||
|
amount: Amount,
|
||||||
|
fee: Fee,
|
||||||
|
memo: String?,
|
||||||
|
destination: String,
|
||||||
|
userWalletId: UserWalletId,
|
||||||
|
network: Network,
|
||||||
|
): TransactionData?
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
package com.tangem.domain.transaction.usecase
|
||||||
|
|
||||||
|
import arrow.core.Either
|
||||||
|
import com.tangem.blockchain.common.Amount
|
||||||
|
import com.tangem.blockchain.common.transaction.Fee
|
||||||
|
import com.tangem.domain.tokens.model.Network
|
||||||
|
import com.tangem.domain.transaction.TransactionRepository
|
||||||
|
import com.tangem.domain.wallets.models.UserWalletId
|
||||||
|
|
||||||
|
class CreateTransactionUseCase(
|
||||||
|
private val transactionRepository: TransactionRepository,
|
||||||
|
) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [REDACTED_TODO_COMMENT]
|
||||||
|
*/
|
||||||
|
@Suppress("LongParameterList")
|
||||||
|
suspend operator fun invoke(
|
||||||
|
amount: Amount,
|
||||||
|
fee: Fee,
|
||||||
|
memo: String?,
|
||||||
|
destination: String,
|
||||||
|
userWalletId: UserWalletId,
|
||||||
|
network: Network,
|
||||||
|
) = Either.catch {
|
||||||
|
requireNotNull(
|
||||||
|
transactionRepository.createTransaction(
|
||||||
|
amount = amount,
|
||||||
|
fee = fee,
|
||||||
|
memo = memo,
|
||||||
|
destination = destination,
|
||||||
|
userWalletId = userWalletId,
|
||||||
|
network = network,
|
||||||
|
),
|
||||||
|
) { "Failed to create transaction" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -14,7 +14,6 @@ import androidx.compose.material3.Icon
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.State
|
import androidx.compose.runtime.State
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
|
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
|
||||||
|
|
@ -77,13 +76,11 @@ private fun SendPrimaryNavigationButton(uiState: SendUiState, modifier: Modifier
|
||||||
val isSending = uiState.sendState?.isSending?.collectAsStateWithLifecycle()?.value ?: false
|
val isSending = uiState.sendState?.isSending?.collectAsStateWithLifecycle()?.value ?: false
|
||||||
val txUrl = uiState.sendState?.txUrl?.collectAsStateWithLifecycle()?.value.orEmpty()
|
val txUrl = uiState.sendState?.txUrl?.collectAsStateWithLifecycle()?.value.orEmpty()
|
||||||
|
|
||||||
val (buttonTextId, buttonClick) = remember {
|
val (buttonTextId, buttonClick) = getButtonData(
|
||||||
getButtonData(
|
|
||||||
currentState = currentState,
|
currentState = currentState,
|
||||||
isSuccess = isSuccess,
|
isSuccess = isSuccess,
|
||||||
uiState = uiState,
|
uiState = uiState,
|
||||||
)
|
)
|
||||||
}
|
|
||||||
|
|
||||||
val isButtonEnabled = isButtonEnabled(
|
val isButtonEnabled = isButtonEnabled(
|
||||||
currentState = currentState,
|
currentState = currentState,
|
||||||
|
|
|
||||||
|
|
@ -1,52 +0,0 @@
|
||||||
package com.tangem.features.send.impl.presentation.viewmodel
|
|
||||||
|
|
||||||
import androidx.core.text.isDigitsOnly
|
|
||||||
import com.tangem.blockchain.common.Blockchain
|
|
||||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
|
||||||
import java.math.BigInteger
|
|
||||||
|
|
||||||
internal fun validateMemo(memo: String, cryptoCurrency: CryptoCurrency?): Boolean {
|
|
||||||
if (cryptoCurrency == null) return false
|
|
||||||
if (memo.isEmpty()) return true
|
|
||||||
return when (cryptoCurrency.network.id.value) {
|
|
||||||
Blockchain.XRP.id -> {
|
|
||||||
val tag = memo.toLongOrNull()
|
|
||||||
tag != null && tag <= XRP_TAG_MAX_NUMBER
|
|
||||||
}
|
|
||||||
Blockchain.Stellar.id -> {
|
|
||||||
isAssignableValue(memo)
|
|
||||||
}
|
|
||||||
else -> true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun isAssignableValue(value: String): Boolean {
|
|
||||||
val memoType = when {
|
|
||||||
value.isNotEmpty() && value.isDigitsOnly() -> XlmMemoType.ID
|
|
||||||
else -> XlmMemoType.TEXT
|
|
||||||
}
|
|
||||||
return when (memoType) {
|
|
||||||
XlmMemoType.TEXT -> {
|
|
||||||
// from org.stellar.sdk.MemoText
|
|
||||||
value.toByteArray().size <= XLM_MEMO_MAX_LENGTH
|
|
||||||
}
|
|
||||||
XlmMemoType.ID -> {
|
|
||||||
try {
|
|
||||||
// from com.tangem.blockchain.blockchains.stellar.StellarMemo.toStellarSdkMemo
|
|
||||||
value.toBigInteger() in BigInteger.ZERO..Long.MAX_VALUE.toBigInteger() * 2.toBigInteger()
|
|
||||||
} catch (ex: NumberFormatException) {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun determineXlmMemoType(value: String): XlmMemoType = when {
|
|
||||||
value.isNotEmpty() && value.isDigitsOnly() -> XlmMemoType.ID
|
|
||||||
else -> XlmMemoType.TEXT
|
|
||||||
}
|
|
||||||
|
|
||||||
enum class XlmMemoType { TEXT, ID }
|
|
||||||
|
|
||||||
private const val XRP_TAG_MAX_NUMBER = 4294967295
|
|
||||||
private const val XLM_MEMO_MAX_LENGTH = 28
|
|
||||||
|
|
@ -6,15 +6,8 @@ import androidx.compose.runtime.setValue
|
||||||
import androidx.lifecycle.*
|
import androidx.lifecycle.*
|
||||||
import androidx.paging.PagingData
|
import androidx.paging.PagingData
|
||||||
import arrow.core.getOrElse
|
import arrow.core.getOrElse
|
||||||
import com.tangem.blockchain.blockchains.binance.BinanceTransactionExtras
|
|
||||||
import com.tangem.blockchain.blockchains.cosmos.CosmosTransactionExtras
|
|
||||||
import com.tangem.blockchain.blockchains.stellar.StellarMemo
|
|
||||||
import com.tangem.blockchain.blockchains.stellar.StellarTransactionExtras
|
|
||||||
import com.tangem.blockchain.blockchains.ton.TonTransactionExtras
|
|
||||||
import com.tangem.blockchain.blockchains.xrp.XrpAddressService
|
import com.tangem.blockchain.blockchains.xrp.XrpAddressService
|
||||||
import com.tangem.blockchain.blockchains.xrp.XrpTransactionBuilder
|
|
||||||
import com.tangem.blockchain.common.Blockchain
|
import com.tangem.blockchain.common.Blockchain
|
||||||
import com.tangem.blockchain.common.TransactionExtras
|
|
||||||
import com.tangem.blockchain.common.transaction.Fee
|
import com.tangem.blockchain.common.transaction.Fee
|
||||||
import com.tangem.blockchain.common.transaction.TransactionFee
|
import com.tangem.blockchain.common.transaction.TransactionFee
|
||||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||||
|
|
@ -25,6 +18,7 @@ import com.tangem.domain.tokens.GetNetworkCoinStatusUseCase
|
||||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||||
import com.tangem.domain.tokens.utils.convertToAmount
|
import com.tangem.domain.tokens.utils.convertToAmount
|
||||||
|
import com.tangem.domain.transaction.usecase.CreateTransactionUseCase
|
||||||
import com.tangem.domain.transaction.usecase.GetFeeUseCase
|
import com.tangem.domain.transaction.usecase.GetFeeUseCase
|
||||||
import com.tangem.domain.transaction.usecase.SendTransactionUseCase
|
import com.tangem.domain.transaction.usecase.SendTransactionUseCase
|
||||||
import com.tangem.domain.txhistory.models.TxHistoryItem
|
import com.tangem.domain.txhistory.models.TxHistoryItem
|
||||||
|
|
@ -57,6 +51,7 @@ import kotlinx.coroutines.awaitAll
|
||||||
import kotlinx.coroutines.coroutineScope
|
import kotlinx.coroutines.coroutineScope
|
||||||
import kotlinx.coroutines.flow.*
|
import kotlinx.coroutines.flow.*
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import timber.log.Timber
|
||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlin.properties.Delegates
|
import kotlin.properties.Delegates
|
||||||
|
|
@ -75,6 +70,7 @@ internal class SendViewModel @Inject constructor(
|
||||||
private val txHistoryItemsCountUseCase: GetTxHistoryItemsCountUseCase,
|
private val txHistoryItemsCountUseCase: GetTxHistoryItemsCountUseCase,
|
||||||
private val getFeeUseCase: GetFeeUseCase,
|
private val getFeeUseCase: GetFeeUseCase,
|
||||||
private val sendTransactionUseCase: SendTransactionUseCase,
|
private val sendTransactionUseCase: SendTransactionUseCase,
|
||||||
|
private val createTransactionUseCase: CreateTransactionUseCase,
|
||||||
private val getExplorerTransactionUrlUseCase: GetExplorerTransactionUrlUseCase,
|
private val getExplorerTransactionUrlUseCase: GetExplorerTransactionUrlUseCase,
|
||||||
private val validateWalletAddressUseCase: ValidateWalletAddressUseCase,
|
private val validateWalletAddressUseCase: ValidateWalletAddressUseCase,
|
||||||
private val walletManagersFacade: WalletManagersFacade,
|
private val walletManagersFacade: WalletManagersFacade,
|
||||||
|
|
@ -135,7 +131,7 @@ internal class SendViewModel @Inject constructor(
|
||||||
getCurrenciesStatusUpdates(owner, wallet)
|
getCurrenciesStatusUpdates(owner, wallet)
|
||||||
},
|
},
|
||||||
ifLeft = {
|
ifLeft = {
|
||||||
// TODO add error handling
|
// todo add error handling [[REDACTED_JIRA]]
|
||||||
return@launch
|
return@launch
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
@ -299,7 +295,7 @@ internal class SendViewModel @Inject constructor(
|
||||||
uiState = stateFactory.onFeeOnLoadedState(it, true)
|
uiState = stateFactory.onFeeOnLoadedState(it, true)
|
||||||
},
|
},
|
||||||
ifLeft = {
|
ifLeft = {
|
||||||
// TODO add error handling
|
// todo add error handling [[REDACTED_JIRA]]
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -421,7 +417,7 @@ internal class SendViewModel @Inject constructor(
|
||||||
|
|
||||||
val amountToSend = amount.toBigDecimal().convertToAmount(cryptoCurrency)
|
val amountToSend = amount.toBigDecimal().convertToAmount(cryptoCurrency)
|
||||||
|
|
||||||
// todo add notifications [[REDACTED_JIRA]]
|
// todo add error handling [[REDACTED_JIRA]]
|
||||||
// val transactionErrors = walletManagersFacade.validateTransaction(
|
// val transactionErrors = walletManagersFacade.validateTransaction(
|
||||||
// amount = amountToSend,
|
// amount = amountToSend,
|
||||||
// fee = fee.amount,
|
// fee = fee.amount,
|
||||||
|
|
@ -429,15 +425,19 @@ internal class SendViewModel @Inject constructor(
|
||||||
// network = cryptoCurrency.network,
|
// network = cryptoCurrency.network,
|
||||||
// )
|
// )
|
||||||
|
|
||||||
val txData = walletManagersFacade.createTransaction(
|
createTransactionUseCase(
|
||||||
amount = amountToSend,
|
amount = amountToSend,
|
||||||
fee = fee,
|
fee = fee,
|
||||||
memo = memo,
|
memo = memo,
|
||||||
destination = recipient,
|
destination = recipient,
|
||||||
userWalletId = userWalletId,
|
userWalletId = userWalletId,
|
||||||
network = cryptoCurrency.network,
|
network = cryptoCurrency.network,
|
||||||
)?.copy(extras = getMemoExtras(cryptoCurrency.network.id.value, memo)) ?: return
|
).fold(
|
||||||
|
ifLeft = {
|
||||||
|
Timber.e(it)
|
||||||
|
// todo add error handling [[REDACTED_JIRA]]
|
||||||
|
},
|
||||||
|
ifRight = { txData ->
|
||||||
sendTransactionUseCase(
|
sendTransactionUseCase(
|
||||||
txData = txData,
|
txData = txData,
|
||||||
userWallet = userWallet,
|
userWallet = userWallet,
|
||||||
|
|
@ -445,7 +445,7 @@ internal class SendViewModel @Inject constructor(
|
||||||
).fold(
|
).fold(
|
||||||
ifLeft = {
|
ifLeft = {
|
||||||
sendState.isSending.update { false }
|
sendState.isSending.update { false }
|
||||||
// todo add notifications [[REDACTED_JIRA]]
|
// todo add error handling [[REDACTED_JIRA]]
|
||||||
},
|
},
|
||||||
ifRight = {
|
ifRight = {
|
||||||
sendState.transactionDate.update {
|
sendState.transactionDate.update {
|
||||||
|
|
@ -457,6 +457,8 @@ internal class SendViewModel @Inject constructor(
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getFee(feeState: FeeSelectorState.Content): Fee? {
|
private fun getFee(feeState: FeeSelectorState.Content): Fee? {
|
||||||
|
|
@ -499,25 +501,6 @@ internal class SendViewModel @Inject constructor(
|
||||||
}
|
}
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
private fun getMemoExtras(networkId: String, memo: String?): TransactionExtras? {
|
|
||||||
val blockchain = Blockchain.fromId(networkId)
|
|
||||||
if (memo == null) return null
|
|
||||||
return when (blockchain) {
|
|
||||||
Blockchain.Stellar -> {
|
|
||||||
val xmlMemo = when (determineXlmMemoType(memo)) {
|
|
||||||
XlmMemoType.TEXT -> StellarMemo.Text(memo)
|
|
||||||
XlmMemoType.ID -> StellarMemo.Id(memo.toBigInteger())
|
|
||||||
}
|
|
||||||
StellarTransactionExtras(xmlMemo)
|
|
||||||
}
|
|
||||||
Blockchain.Binance -> BinanceTransactionExtras(memo)
|
|
||||||
Blockchain.XRP -> memo.toLongOrNull()?.let { XrpTransactionBuilder.XrpTransactionExtras(it) }
|
|
||||||
Blockchain.Cosmos -> CosmosTransactionExtras(memo)
|
|
||||||
Blockchain.TON -> TonTransactionExtras(memo)
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val XRP_X_ADDRESS = 'X'
|
private const val XRP_X_ADDRESS = 'X'
|
||||||
private const val DEFAULT_VALUE = "0.00"
|
private const val DEFAULT_VALUE = "0.00"
|
||||||
|
|
|
||||||
|
|
@ -143,4 +143,5 @@ include(":data:settings")
|
||||||
include(":data:txhistory")
|
include(":data:txhistory")
|
||||||
include(":data:wallets")
|
include(":data:wallets")
|
||||||
include(":data:analytics")
|
include(":data:analytics")
|
||||||
|
include(":data:transaction")
|
||||||
// endregion Data modules
|
// endregion Data modules
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue