Updated on 2026-08-14
This commit is contained in:
parent
2f2d6755f9
commit
5f4dfefc2e
20 changed files with 190 additions and 311 deletions
|
|
@ -21,4 +21,10 @@ abstract class SingleAccountListSupplier(
|
|||
params = SingleAccountListProducer.Params(userWalletId = userWalletId),
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun getSyncOrNull(userWalletId: UserWalletId): AccountList? {
|
||||
return getSyncOrNull(
|
||||
params = SingleAccountListProducer.Params(userWalletId = userWalletId),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -20,4 +20,9 @@ abstract class SingleAccountStatusListSupplier(
|
|||
val params = SingleAccountStatusListProducer.Params(userWalletId)
|
||||
return this.invoke(params)
|
||||
}
|
||||
|
||||
suspend fun getSyncOrNull(userWalletId: UserWalletId): AccountStatusList? {
|
||||
val params = SingleAccountStatusListProducer.Params(userWalletId)
|
||||
return this.getSyncOrNull(params)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,106 +0,0 @@
|
|||
package com.tangem.domain.tokens
|
||||
|
||||
import arrow.core.Either
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.tokens.error.CurrencyStatusError
|
||||
import com.tangem.domain.tokens.error.mapper.mapToCurrencyError
|
||||
import com.tangem.domain.tokens.operations.BaseCurrencyStatusOperations
|
||||
import com.tangem.domain.tokens.operations.CurrenciesStatusesOperations
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.flow.*
|
||||
|
||||
/**
|
||||
* Use case for fetching the status of a cryptocurrency associated with a user wallet.
|
||||
*
|
||||
*/
|
||||
class GetSingleCryptoCurrencyStatusUseCase(
|
||||
private val currencyStatusOperations: BaseCurrencyStatusOperations,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
) {
|
||||
|
||||
/**
|
||||
* Returns cryptocurrency status flow for Multi-Currency wallet
|
||||
*
|
||||
* @param userWalletId The unique identifier of the user's wallet.
|
||||
* @param currencyId The unique identifier of the cryptocurrency.
|
||||
* @param isSingleWalletWithTokens Indicates whether the user wallet contains only one token on card (old cards)
|
||||
* @return A [Flow] emitting either a [CurrencyStatusError] or a [CryptoCurrencyStatus], indicating the result of the fetch operation.
|
||||
*/
|
||||
fun invokeMultiWallet(
|
||||
userWalletId: UserWalletId,
|
||||
currencyId: CryptoCurrency.ID,
|
||||
isSingleWalletWithTokens: Boolean,
|
||||
): Flow<Either<CurrencyStatusError, CryptoCurrencyStatus>> {
|
||||
return flow {
|
||||
emitAll(
|
||||
getCurrencyStatus(
|
||||
userWalletId = userWalletId,
|
||||
currencyId = currencyId,
|
||||
isSingleWalletWithTokens = isSingleWalletWithTokens,
|
||||
),
|
||||
)
|
||||
}.flowOn(dispatchers.io)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns cryptocurrency status flow for primary currency for Single-Currency wallet
|
||||
*
|
||||
* @param userWalletId The unique identifier of the user's wallet.
|
||||
* @return A [Flow] emitting either a [CurrencyStatusError] or a [CryptoCurrencyStatus], indicating the result of the fetch operation.
|
||||
*/
|
||||
fun invokeSingleWallet(userWalletId: UserWalletId): Flow<Either<CurrencyStatusError, CryptoCurrencyStatus>> {
|
||||
return flow {
|
||||
emitAll(
|
||||
currencyStatusOperations.getPrimaryCurrencyStatusFlow(userWalletId).map { maybeCurrency ->
|
||||
maybeCurrency.mapLeft(CurrenciesStatusesOperations.Error::mapToCurrencyError)
|
||||
},
|
||||
)
|
||||
}.flowOn(dispatchers.io)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns synchronously cryptocurrency status for Multi-Currency wallet
|
||||
*
|
||||
* @param userWalletId The unique identifier of the user's wallet.
|
||||
* @param cryptoCurrencyId The unique identifier of the cryptocurrency.
|
||||
* @param isSingleWalletWithTokens Indicates whether the user wallet contains only one token on card (old cards)
|
||||
* @return A [Flow] emitting either a [CurrencyStatusError] or a [CryptoCurrencyStatus], indicating the result of the fetch operation.
|
||||
*/
|
||||
suspend fun invokeMultiWalletSync(
|
||||
userWalletId: UserWalletId,
|
||||
cryptoCurrencyId: CryptoCurrency.ID,
|
||||
isSingleWalletWithTokens: Boolean = false,
|
||||
): Either<CurrencyStatusError, CryptoCurrencyStatus> {
|
||||
return currencyStatusOperations.getCurrencyStatusSync(userWalletId, cryptoCurrencyId, isSingleWalletWithTokens)
|
||||
.mapLeft { error -> error.mapToCurrencyError() }
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns synchronously cryptocurrency status for primary currency for Single-Currency wallet
|
||||
*
|
||||
* @param userWalletId The unique identifier of the user's wallet.
|
||||
* @return A [Flow] emitting either a [CurrencyStatusError] or a [CryptoCurrencyStatus], indicating the result of the fetch operation.
|
||||
*/
|
||||
suspend fun invokeSingleWalletSync(userWalletId: UserWalletId): Either<CurrencyStatusError, CryptoCurrencyStatus> {
|
||||
return currencyStatusOperations.getPrimaryCurrencyStatusSync(userWalletId)
|
||||
.mapLeft { error -> error.mapToCurrencyError() }
|
||||
}
|
||||
|
||||
private suspend fun getCurrencyStatus(
|
||||
userWalletId: UserWalletId,
|
||||
currencyId: CryptoCurrency.ID,
|
||||
isSingleWalletWithTokens: Boolean,
|
||||
): Flow<Either<CurrencyStatusError, CryptoCurrencyStatus>> {
|
||||
val currencyFlow = currencyStatusOperations.getCurrencyStatusFlow(
|
||||
userWalletId = userWalletId,
|
||||
currencyId = currencyId,
|
||||
isSingleWalletWithTokens = isSingleWalletWithTokens,
|
||||
)
|
||||
|
||||
return currencyFlow.map { maybeCurrency ->
|
||||
maybeCurrency.mapLeft(CurrenciesStatusesOperations.Error::mapToCurrencyError)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -26,6 +26,7 @@ dependencies {
|
|||
implementation(projects.libs.blockchainSdk)
|
||||
implementation(projects.libs.crypto)
|
||||
|
||||
implementation(projects.domain.account.status)
|
||||
implementation(projects.domain.models)
|
||||
implementation(projects.domain.legacy)
|
||||
implementation(projects.domain.walletManager)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.domain.transaction.usecase.gasless
|
||||
|
||||
import arrow.core.Either
|
||||
import arrow.core.getOrElse
|
||||
import arrow.core.raise.catch
|
||||
import arrow.core.raise.either
|
||||
import com.tangem.blockchain.blockchains.ethereum.EthereumTransactionExtras
|
||||
|
|
@ -16,13 +17,13 @@ import com.tangem.blockchain.yieldsupply.providers.ethereum.yield.EthereumYieldS
|
|||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.common.extensions.toDecompressedPublicKey
|
||||
import com.tangem.common.extensions.toHexString
|
||||
import com.tangem.domain.account.status.utils.CryptoCurrencyOperations.getCryptoCurrency
|
||||
import com.tangem.domain.account.supplier.SingleAccountListSupplier
|
||||
import com.tangem.domain.card.common.TapWorkarounds.isTangemTwins
|
||||
import com.tangem.domain.card.models.TwinKey
|
||||
import com.tangem.domain.card.repository.CardSdkConfigRepository
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.tokens.GetSingleCryptoCurrencyStatusUseCase
|
||||
import com.tangem.domain.transaction.GaslessTransactionRepository
|
||||
import com.tangem.domain.transaction.error.SendTransactionError
|
||||
import com.tangem.domain.transaction.models.Eip7702Authorization
|
||||
|
|
@ -33,7 +34,7 @@ import java.math.BigInteger
|
|||
|
||||
class CreateAndSendGaslessTransactionUseCase(
|
||||
private val walletManagersFacade: WalletManagersFacade,
|
||||
private val getSingleCryptoCurrencyStatusUseCase: GetSingleCryptoCurrencyStatusUseCase,
|
||||
private val singleAccountListSupplier: SingleAccountListSupplier,
|
||||
private val gaslessTransactionRepository: GaslessTransactionRepository,
|
||||
private val cardSdkConfigRepository: CardSdkConfigRepository,
|
||||
private val getHotWalletSigner: (UserWallet.Hot) -> TransactionSigner,
|
||||
|
|
@ -74,18 +75,17 @@ class CreateAndSendGaslessTransactionUseCase(
|
|||
transactionData: TransactionData.Uncompiled,
|
||||
fee: TransactionFeeExtended,
|
||||
): GaslessContext {
|
||||
val tokenForFeeStatus = getSingleCryptoCurrencyStatusUseCase.invokeMultiWalletSync(
|
||||
userWallet.walletId,
|
||||
fee.feeTokenId,
|
||||
).getOrNull() ?: error("Token for fee not found")
|
||||
val currency = singleAccountListSupplier.getSyncOrNull(userWalletId = userWallet.walletId)
|
||||
.getCryptoCurrency(currencyId = fee.feeTokenId, network = null)
|
||||
.getOrElse { error("Token for fee not found") }
|
||||
|
||||
val walletManager = walletManagersFacade.getOrCreateWalletManager(
|
||||
userWallet.walletId,
|
||||
tokenForFeeStatus.currency.network,
|
||||
) ?: error("WalletManager not found for network ${tokenForFeeStatus.currency.network.id}")
|
||||
currency.network,
|
||||
) ?: error("WalletManager not found for network ${currency.network.id}")
|
||||
|
||||
val gaslessDataProvider = walletManager as? EthereumGaslessDataProvider ?: error(
|
||||
"WalletManager for network ${tokenForFeeStatus.currency.network.id} " +
|
||||
"WalletManager for network ${currency.network.id} " +
|
||||
"does not support gasless transactions",
|
||||
)
|
||||
|
||||
|
|
@ -94,16 +94,16 @@ class CreateAndSendGaslessTransactionUseCase(
|
|||
val gaslessTransactionData = createGaslessTransactionData(
|
||||
transactionData = transactionData,
|
||||
txFee = fee,
|
||||
tokenFeeStatus = tokenForFeeStatus,
|
||||
currency = currency,
|
||||
nonce = gaslessContractNonce,
|
||||
)
|
||||
|
||||
val chainId = gaslessTransactionRepository.getChainIdForNetwork(tokenForFeeStatus.currency.network)
|
||||
val chainId = gaslessTransactionRepository.getChainIdForNetwork(currency.network)
|
||||
|
||||
return GaslessContext(
|
||||
walletManager = walletManager,
|
||||
gaslessDataProvider = gaslessDataProvider,
|
||||
tokenForFeeStatus = tokenForFeeStatus,
|
||||
currency = currency,
|
||||
gaslessTransactionData = gaslessTransactionData,
|
||||
chainId = chainId,
|
||||
)
|
||||
|
|
@ -189,7 +189,7 @@ class CreateAndSendGaslessTransactionUseCase(
|
|||
transactionData: TransactionData.Uncompiled,
|
||||
): String {
|
||||
val txHash = gaslessTransactionRepository.signGaslessTransaction(
|
||||
network = context.tokenForFeeStatus.currency.network,
|
||||
network = context.currency.network,
|
||||
gaslessTransactionData = context.gaslessTransactionData,
|
||||
signature = signedData.eip712Signature,
|
||||
userAddress = transactionData.sourceAddress,
|
||||
|
|
@ -244,11 +244,11 @@ class CreateAndSendGaslessTransactionUseCase(
|
|||
private suspend fun createGaslessTransactionData(
|
||||
transactionData: TransactionData.Uncompiled,
|
||||
txFee: TransactionFeeExtended,
|
||||
tokenFeeStatus: CryptoCurrencyStatus,
|
||||
currency: CryptoCurrency,
|
||||
nonce: BigInteger,
|
||||
): GaslessTransactionData {
|
||||
val transaction = buildTransaction(transactionData)
|
||||
val fee = buildFee(txFee, tokenFeeStatus)
|
||||
val fee = buildFee(txFee, currency)
|
||||
|
||||
return GaslessTransactionData(
|
||||
transaction = transaction,
|
||||
|
|
@ -272,11 +272,8 @@ class CreateAndSendGaslessTransactionUseCase(
|
|||
)
|
||||
}
|
||||
|
||||
private suspend fun buildFee(
|
||||
txFee: TransactionFeeExtended,
|
||||
tokenFeeStatus: CryptoCurrencyStatus,
|
||||
): GaslessTransactionData.Fee {
|
||||
val tokenForFee = tokenFeeStatus.currency as? CryptoCurrency.Token
|
||||
private suspend fun buildFee(txFee: TransactionFeeExtended, currency: CryptoCurrency): GaslessTransactionData.Fee {
|
||||
val tokenForFee = currency as? CryptoCurrency.Token
|
||||
?: error("Fee currency must be a token")
|
||||
|
||||
val feeInTokenCurrency = txFee.transactionFee.normal as? Fee.Ethereum.TokenCurrency
|
||||
|
|
@ -320,7 +317,7 @@ class CreateAndSendGaslessTransactionUseCase(
|
|||
private data class GaslessContext(
|
||||
val walletManager: WalletManager,
|
||||
val gaslessDataProvider: EthereumGaslessDataProvider,
|
||||
val tokenForFeeStatus: CryptoCurrencyStatus,
|
||||
val currency: CryptoCurrency,
|
||||
val gaslessTransactionData: GaslessTransactionData,
|
||||
val chainId: Int,
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue