Skip to content

Commit

Permalink
Refactor code in SendBitcoin module
Browse files Browse the repository at this point in the history
  • Loading branch information
rafaelekol committed Jan 12, 2024
1 parent 940a766 commit 29f27fa
Show file tree
Hide file tree
Showing 10 changed files with 48 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ interface ILocalStorage {
var pinRandomized: Boolean
var utxoExpertModeEnabled: Boolean

val utxoExpertModeEnabledFlow: StateFlow<Boolean>

fun getSwapProviderId(blockchainType: BlockchainType): String?
fun setSwapProviderId(blockchainType: BlockchainType, providerId: String)

Expand Down Expand Up @@ -316,7 +318,7 @@ interface ISendBitcoinAdapter {
): BigDecimal

fun minimumSendAmount(address: String?): BigDecimal?
fun sendInfo(
fun bitcoinFeeInfo(
amount: BigDecimal,
feeRate: Int,
address: String?,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ abstract class BitcoinBaseAdapter(
}
}

fun sendInfo(
fun bitcoinFeeInfo(
amount: BigDecimal,
feeRate: Int,
address: String?,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ class LocalStorageManager(
private val PIN_RANDOMIZED = "pin_randomized"
private val UTXO_EXPERT_MODE = "utxo_expert_mode"

private val _utxoExpertModeEnabledFlow = MutableStateFlow(false)
override val utxoExpertModeEnabledFlow = _utxoExpertModeEnabledFlow

private val gson by lazy { Gson() }

override var chartIndicatorsEnabled: Boolean
Expand Down Expand Up @@ -504,6 +507,9 @@ class LocalStorageManager(
get() = preferences.getBoolean(UTXO_EXPERT_MODE, false)
set(value) {
preferences.edit().putBoolean(UTXO_EXPERT_MODE, value).apply()
_utxoExpertModeEnabledFlow.update {
value
}
}

private fun getSwapProviderKey(blockchainType: BlockchainType): String {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ import kotlinx.coroutines.flow.update

class SendBitcoinAddressService(private val adapter: ISendBitcoinAdapter, filledAddress: String?) {

var address: Address? = filledAddress?.let { Address(it) }
private set
private var address: Address? = filledAddress?.let { Address(it) }
private var validAddress: Address? = filledAddress?.let { Address(it) }
private var addressError: Throwable? = null

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ class SendBitcoinAmountService(
private val coinCode: String,
private val amountValidator: AmountValidator
) {
var amount: BigDecimal? = null
private set
private var amount: BigDecimal? = null
private var customUnspentOutputs: List<UnspentOutputInfo>? = null
private var amountCaution: HSCaution? = null

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ import kotlinx.coroutines.withContext
class SendBitcoinFeeRateService(private val feeRateProvider: IFeeRateProvider) {
val feeRateChangeable = feeRateProvider.feeRateChangeable

var feeRate: Int? = null
private set
private var feeRate: Int? = null
private var feeRateCaution: HSCaution? = null
private var canBeSend = false

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ import kotlinx.coroutines.flow.update
import java.math.BigDecimal

class SendBitcoinFeeService(private val adapter: ISendBitcoinAdapter) {
private val _feeDataFlow = MutableStateFlow<BitcoinFeeInfo?>(null)
val feeDataFlow = _feeDataFlow.asStateFlow()
private val _bitcoinFeeInfoFlow = MutableStateFlow<BitcoinFeeInfo?>(null)
val bitcoinFeeInfoFlow = _bitcoinFeeInfoFlow.asStateFlow()

private var feeData: BitcoinFeeInfo? = null
private var bitcoinFeeInfo: BitcoinFeeInfo? = null
private var customUnspentOutputs: List<UnspentOutputInfo>? = null

private var amount: BigDecimal? = null
Expand All @@ -23,52 +23,52 @@ class SendBitcoinFeeService(private val adapter: ISendBitcoinAdapter) {

private var feeRate: Int? = null

private fun refreshFee() {
private fun refreshFeeInfo() {
val tmpAmount = amount
val tmpFeeRate = feeRate

feeData = when {
bitcoinFeeInfo = when {
tmpAmount == null -> null
tmpFeeRate == null -> null
else -> adapter.sendInfo(tmpAmount, tmpFeeRate, validAddress?.hex, customUnspentOutputs, pluginData)
else -> adapter.bitcoinFeeInfo(tmpAmount, tmpFeeRate, validAddress?.hex, customUnspentOutputs, pluginData)
}
}

private fun emitState() {
_feeDataFlow.update { feeData }
_bitcoinFeeInfoFlow.update { bitcoinFeeInfo }
}

fun setAmount(amount: BigDecimal?) {
this.amount = amount

refreshFee()
refreshFeeInfo()
emitState()
}

fun setValidAddress(validAddress: Address?) {
this.validAddress = validAddress

refreshFee()
refreshFeeInfo()
emitState()
}

fun setPluginData(pluginData: Map<Byte, IPluginData>?) {
this.pluginData = pluginData

refreshFee()
refreshFeeInfo()
emitState()
}

fun setFeeRate(feeRate: Int?) {
this.feeRate = feeRate

refreshFee()
refreshFeeInfo()
emitState()
}

fun setCustomUnspentOutputs(customUnspentOutputs: List<UnspentOutputInfo>?) {
this.customUnspentOutputs = customUnspentOutputs
refreshFee()
refreshFeeInfo()
emitState()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ import io.horizontalsystems.bankwallet.modules.send.bitcoin.advanced.SendBtcAdva
import io.horizontalsystems.bankwallet.modules.send.bitcoin.utxoexpert.UtxoExpertModeScreen
import io.horizontalsystems.bankwallet.modules.sendtokenselect.PrefilledData
import io.horizontalsystems.bankwallet.ui.compose.ComposeAppTheme
import io.horizontalsystems.bankwallet.ui.compose.DisposableLifecycleCallbacks
import io.horizontalsystems.bankwallet.ui.compose.TranslatableString
import io.horizontalsystems.bankwallet.ui.compose.components.AppBar
import io.horizontalsystems.bankwallet.ui.compose.components.ButtonPrimaryYellow
Expand Down Expand Up @@ -99,9 +98,9 @@ fun SendBitcoinNavHost(
UtxoExpertModeScreen(
adapter = viewModel.adapter,
token = viewModel.wallet.token,
address = viewModel.address,
value = viewModel.amount,
feeRate = viewModel.feeRate,
address = viewModel.uiState.address,
value = viewModel.uiState.amount,
feeRate = viewModel.uiState.feeRate,
customUnspentOutputs = viewModel.customUnspentOutputs,
updateUnspentOutputs = {
viewModel.updateCustomUnspentOutputs(it)
Expand Down Expand Up @@ -142,12 +141,6 @@ fun SendBitcoinScreen(
)
val amountUnique = paymentAddressViewModel.amountUnique

DisposableLifecycleCallbacks(
onResume = {
viewModel.onResume()
},
)

ComposeAppTheme {
val focusRequester = remember { FocusRequester() }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,6 @@ class SendBitcoinViewModel(
private val showAddressInput: Boolean,
private val localStorage: ILocalStorage,
) : ViewModel() {
val address by addressService::address
val amount by amountService::amount
val feeRate by feeRateService::feeRate
val coinMaxAllowedDecimals = wallet.token.decimals
val fiatMaxAllowedDecimals = App.appConfigProvider.fiatDecimal

Expand All @@ -60,7 +57,7 @@ class SendBitcoinViewModel(
private var amountState = amountService.stateFlow.value
private var addressState = addressService.stateFlow.value
private var pluginState = pluginService.stateFlow.value
private var fee: BigDecimal? = feeService.feeDataFlow.value?.fee
private var fee: BigDecimal? = feeService.bitcoinFeeInfoFlow.value?.fee
private var utxoData = SendBitcoinModule.UtxoData()

private val logger = AppLogger("Send-${wallet.coin.code}")
Expand All @@ -73,7 +70,9 @@ class SendBitcoinViewModel(
var uiState by mutableStateOf(
SendBitcoinUiState(
availableBalance = amountState.availableBalance,
amount = amountState.amount,
feeRate = feeRateState.feeRate,
address = addressState.validAddress,
fee = fee,
lockTimeInterval = pluginState.lockTimeInterval,
addressError = addressState.addressError,
Expand Down Expand Up @@ -102,12 +101,16 @@ class SendBitcoinViewModel(
pluginService.stateFlow.collectWith(viewModelScope) {
handleUpdatedPluginState(it)
}
feeService.feeDataFlow.collectWith(viewModelScope) {
handleUpdatedFeeData(it)
feeService.bitcoinFeeInfoFlow.collectWith(viewModelScope) {
handleUpdatedFeeInfo(it)
}
xRateService.getRateFlow(wallet.coin.uid).collectWith(viewModelScope) {
coinRate = it
}
localStorage.utxoExpertModeEnabledFlow.collectWith(viewModelScope) { enabled ->
utxoExpertModeEnabled = enabled
emitState()
}

viewModelScope.launch {
feeRateService.start()
Expand All @@ -117,7 +120,9 @@ class SendBitcoinViewModel(
private fun emitState() {
val newUiState = SendBitcoinUiState(
availableBalance = amountState.availableBalance,
amount = amountState.amount,
feeRate = feeRateState.feeRate,
address = addressState.validAddress,
fee = fee,
lockTimeInterval = pluginState.lockTimeInterval,
addressError = addressState.addressError,
Expand Down Expand Up @@ -177,10 +182,6 @@ class SendBitcoinViewModel(
emitState()
}

fun onResume() {
emitState()
}

private fun updateUtxoData(usedUtxosSize: Int) {
utxoData = SendBitcoinModule.UtxoData(
type = if (customUnspentOutputs == null) SendBitcoinModule.UtxoType.Auto else SendBitcoinModule.UtxoType.Manual,
Expand Down Expand Up @@ -224,7 +225,7 @@ class SendBitcoinViewModel(
emitState()
}

private fun handleUpdatedFeeData(info: BitcoinFeeInfo?) {
private fun handleUpdatedFeeInfo(info: BitcoinFeeInfo?) {
fee = info?.fee
if (info == null && customUnspentOutputs == null) {
utxoData = SendBitcoinModule.UtxoData()
Expand Down Expand Up @@ -293,8 +294,10 @@ class SendBitcoinViewModel(

data class SendBitcoinUiState(
val availableBalance: BigDecimal?,
val amount: BigDecimal?,
val fee: BigDecimal?,
val feeRate: Int?,
val address: Address?,
val lockTimeInterval: LockTimeInterval?,
val addressError: Throwable?,
val amountCaution: HSCaution?,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,19 +91,20 @@ class UtxoExpertModeViewModel(

private fun updateFee() {
val feeRateNonNull = feeRate ?: return
val sendInfo = adapter.sendInfo(
val bitcoinFeeInfo = adapter.bitcoinFeeInfo(
amount = value,
feeRate = feeRateNonNull,
address = address?.hex,
unspentOutputs = customOutputs,
pluginData = null,
)
val fee = sendInfo?.fee
val fee = bitcoinFeeInfo?.fee
if (fee == null) {
feeInfo = feeInfo.copy(
value = null,
subValue = null,
)
changeInfo = null
return
}
feeInfo = feeInfo.copy(
Expand All @@ -112,10 +113,10 @@ class UtxoExpertModeViewModel(
rate.copy(value = fee.times(rate.value)).getFormattedFull()
} ?: "",
)
changeInfo = if (sendInfo.changeAddress != null && sendInfo.changeValue != null) {
val value = sendInfo.changeValue
changeInfo = if (bitcoinFeeInfo.changeAddress != null && bitcoinFeeInfo.changeValue != null) {
val value = bitcoinFeeInfo.changeValue
UtxoExpertModeModule.InfoItem(
subTitle = sendInfo.changeAddress.stringValue.shorten(),
subTitle = bitcoinFeeInfo.changeAddress.stringValue.shorten(),
value = App.numberFormatter.formatCoinFull(value, token.coin.code, token.decimals),
subValue = coinRate?.let { rate ->
rate.copy(value = value.times(rate.value)).getFormattedFull()
Expand Down

0 comments on commit 29f27fa

Please sign in to comment.