Skip to content

Commit

Permalink
Handle initial nonce and gas price for wc send tx request
Browse files Browse the repository at this point in the history
  • Loading branch information
abdrasulov committed May 21, 2024
1 parent 2f772b7 commit 2448a3b
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,28 +50,41 @@ import io.horizontalsystems.bankwallet.ui.compose.components.MenuItem
import io.horizontalsystems.ethereumkit.core.LegacyGasPriceProvider
import io.horizontalsystems.ethereumkit.core.eip1559.Eip1559GasPriceProvider
import io.horizontalsystems.ethereumkit.decorations.TransactionDecoration
import io.horizontalsystems.ethereumkit.models.GasPrice
import io.horizontalsystems.ethereumkit.models.TransactionData
import io.horizontalsystems.marketkit.models.BlockchainType
import io.reactivex.Flowable
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.rx2.await
import java.math.BigDecimal

class SendTransactionServiceEvm(blockchainType: BlockchainType) : ISendTransactionService() {
class SendTransactionServiceEvm(
blockchainType: BlockchainType,
initialGasPrice: GasPrice? = null,
initialNonce: Long? = null
) : ISendTransactionService() {
private val token by lazy { App.evmBlockchainManager.getBaseToken(blockchainType)!! }
private val evmKitWrapper by lazy { App.evmBlockchainManager.getEvmKitManager(blockchainType).evmKitWrapper!! }
private val gasPriceService: IEvmGasPriceService by lazy {
val evmKit = evmKitWrapper.evmKit
if (evmKit.chain.isEIP1559Supported) {
val gasPriceProvider = Eip1559GasPriceProvider(evmKit)
Eip1559GasPriceService(gasPriceProvider, Flowable.empty())
Eip1559GasPriceService(
gasProvider = gasPriceProvider,
refreshSignalFlowable = Flowable.empty(),
initialGasPrice = initialGasPrice as? GasPrice.Eip1559
)
} else {
val gasPriceProvider = LegacyGasPriceProvider(evmKit)
LegacyGasPriceService(gasPriceProvider)
LegacyGasPriceService(
gasPriceProvider = gasPriceProvider,
initialGasPrice = (initialGasPrice as? GasPrice.Legacy)?.legacyGasPrice
)
}
}
private val feeService by lazy {
Expand All @@ -89,7 +102,9 @@ class SendTransactionServiceEvm(blockchainType: BlockchainType) : ISendTransacti
App.coinManager
)
}
private val nonceService by lazy { SendEvmNonceService(evmKitWrapper.evmKit) }
private val nonceService by lazy {
SendEvmNonceService(evmKitWrapper.evmKit, initialNonce)
}
private val settingsService by lazy { SendEvmSettingsService(feeService, nonceService) }

private val baseCoinService = coinServiceFactory.baseCoinService
Expand Down Expand Up @@ -129,7 +144,7 @@ class SendTransactionServiceEvm(blockchainType: BlockchainType) : ISendTransacti
coroutineScope.launch {
settingsService.start()
}
coroutineScope.launch {
coroutineScope.launch(Dispatchers.Default) {
nonceService.start()
}
coroutineScope.launch {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ import kotlinx.coroutines.withContext

class SendEvmNonceService(
private val evmKit: EthereumKit,
private var fixedNonce: Long? = null
private val initialNonce: Long? = null,
) {
private var fixedNonce: Long? = null
private var latestNonce: Long? = null

var state: DataState<State> = DataState.Loading
Expand All @@ -28,11 +29,14 @@ class SendEvmNonceService(
val stateFlow: Flow<DataState<State>> = _stateFlow

suspend fun start() {
latestNonce = evmKit.getNonce(DefaultBlockParameter.Latest).await()

val fixedNonce = fixedNonce
if (fixedNonce != null) {
sync(fixedNonce)
} else {
setRecommended()

when {
fixedNonce != null -> sync(fixedNonce)
initialNonce != null -> sync(initialNonce)
else -> setRecommended()
}
}

Expand Down Expand Up @@ -85,8 +89,6 @@ class SendEvmNonceService(
try {
val nonce = evmKit.getNonce(DefaultBlockParameter.Pending).await()
sync(nonce, default = true)

latestNonce = evmKit.getNonce(DefaultBlockParameter.Latest).await()
} catch (e: Throwable) {
state = DataState.Error(e)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import io.horizontalsystems.bankwallet.core.ethereum.EvmCoinServiceFactory
import io.horizontalsystems.bankwallet.core.providers.Translator
import io.horizontalsystems.bankwallet.modules.multiswap.sendtransaction.SendTransactionData
import io.horizontalsystems.bankwallet.modules.multiswap.sendtransaction.SendTransactionServiceEvm
import io.horizontalsystems.bankwallet.modules.multiswap.sendtransaction.SendTransactionServiceState
import io.horizontalsystems.bankwallet.modules.multiswap.ui.DataField
import io.horizontalsystems.bankwallet.modules.send.SendModule
import io.horizontalsystems.bankwallet.modules.sendevmtransaction.SectionViewItem
Expand All @@ -20,6 +21,7 @@ import io.horizontalsystems.bankwallet.modules.sendevmtransaction.ViewItem
import io.horizontalsystems.bankwallet.modules.walletconnect.WCDelegate
import io.horizontalsystems.bankwallet.modules.walletconnect.request.WCChainData
import io.horizontalsystems.core.toHexString
import io.horizontalsystems.ethereumkit.models.GasPrice
import io.horizontalsystems.ethereumkit.models.TransactionData
import io.horizontalsystems.marketkit.models.BlockchainType
import kotlinx.coroutines.Dispatchers
Expand All @@ -28,19 +30,32 @@ import kotlinx.coroutines.withContext

class WCSendEthereumTransactionRequestViewModel(
private val sendEvmTransactionViewItemFactory: SendEvmTransactionViewItemFactory,
val sendTransactionService: SendTransactionServiceEvm,
private val dAppName: String,
transaction: WalletConnectTransaction
transaction: WalletConnectTransaction,
blockchainType: BlockchainType
) : ViewModelUiState<WCSendEthereumTransactionRequestUiState>() {
val sendTransactionService: SendTransactionServiceEvm

private val transactionData = TransactionData(
transaction.to,
transaction.value,
transaction.data
)

private var sendTransactionState = sendTransactionService.stateFlow.value
private var sendTransactionState: SendTransactionServiceState

init {
val gasPrice = if (transaction.maxFeePerGas != null && transaction.maxPriorityFeePerGas != null) {
GasPrice.Eip1559(transaction.maxFeePerGas, transaction.maxPriorityFeePerGas)
} else if (transaction.gasPrice != null) {
GasPrice.Legacy(transaction.gasPrice)
} else {
null
}

sendTransactionService = SendTransactionServiceEvm(blockchainType, gasPrice, transaction.nonce)
sendTransactionState = sendTransactionService.stateFlow.value

viewModelScope.launch {
sendTransactionService.stateFlow.collect { transactionState ->
sendTransactionState = transactionState
Expand Down Expand Up @@ -114,7 +129,6 @@ class WCSendEthereumTransactionRequestViewModel(
) : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(modelClass: Class<T>): T {
val sendTransactionService = SendTransactionServiceEvm(blockchainType)
val feeToken = App.evmBlockchainManager.getBaseToken(blockchainType)!!
val coinServiceFactory = EvmCoinServiceFactory(
feeToken,
Expand All @@ -132,9 +146,9 @@ class WCSendEthereumTransactionRequestViewModel(

return WCSendEthereumTransactionRequestViewModel(
sendEvmTransactionViewItemFactory,
sendTransactionService,
peerName,
transaction
transaction,
blockchainType
) as T
}
}
Expand Down

0 comments on commit 2448a3b

Please sign in to comment.