@@ -303,7 +303,7 @@ class AppViewModel @Inject constructor(
303303
304304 SendEvent .SpeedAndFee -> setSendEffect(SendEffect .NavigateToFee )
305305 SendEvent .SwipeToPay -> onSwipeToPay()
306- SendEvent .ConfirmAmountWarning -> onConfirmAmountWarning()
306+ is SendEvent .ConfirmAmountWarning -> onConfirmAmountWarning(it.warning )
307307 SendEvent .DismissAmountWarning -> onDismissAmountWarning()
308308 SendEvent .PayConfirmed -> onConfirmPay()
309309 SendEvent .BackToAmount -> setSendEffect(SendEffect .PopBack (SendRoute .Amount ))
@@ -828,29 +828,36 @@ class AppViewModel @Inject constructor(
828828 val amount = _sendUiState .value.amount
829829
830830 handleSanityChecks(amount)
831- if (_sendUiState .value.showAmountWarningDialog != null ) return @launch // await for dialog UI interaction
831+ if (_sendUiState .value.showSanityWarningDialog != null ) return @launch // await for dialog UI interaction
832832
833833 _sendUiState .update { it.copy(shouldConfirmPay = true ) }
834834 }
835835 }
836836
837837 private suspend fun handleSanityChecks (amountSats : ULong ) {
838- if (_sendUiState .value.showAmountWarningDialog != null ) return
838+ if (_sendUiState .value.showSanityWarningDialog != null ) return
839839
840840 val settings = settingsStore.data.first()
841- val amountInUsd = currencyRepo.convertSatsToFiat(amountSats.toLong(), " USD" ).getOrNull() ? : return
842- if (amountInUsd.value > BigDecimal (SEND_AMOUNT_WARNING_THRESHOLD ) && settings.enableSendAmountWarning) {
841+
842+ if (
843+ amountSats > BigDecimal .valueOf(walletRepo.balanceState.value.totalSats.toLong())
844+ .times(BigDecimal (MAX_BALANCE_FRACTION )).toLong().toUInt() &&
845+ SanityWarning .OVER_HALF_BALANCE !in _sendUiState .value.confirmedWarnings
846+ ) {
843847 _sendUiState .update {
844- it.copy(showAmountWarningDialog = AmountWarning . VALUE_OVER_100_USD )
848+ it.copy(showSanityWarningDialog = SanityWarning . OVER_HALF_BALANCE )
845849 }
846850 return
847851 }
848852
849- if (amountSats > BigDecimal .valueOf(walletRepo.balanceState.value.totalSats.toLong())
850- .times(BigDecimal (0.5 )).toLong().toUInt()
853+ val amountInUsd = currencyRepo.convertSatsToFiat(amountSats.toLong(), " USD" ).getOrNull() ? : return
854+ if (
855+ amountInUsd.value > BigDecimal (SEND_AMOUNT_WARNING_THRESHOLD ) &&
856+ settings.enableSendAmountWarning &&
857+ SanityWarning .VALUE_OVER_100_USD !in _sendUiState .value.confirmedWarnings
851858 ) {
852859 _sendUiState .update {
853- it.copy(showAmountWarningDialog = AmountWarning . OVER_HALF_BALANCE )
860+ it.copy(showSanityWarningDialog = SanityWarning . VALUE_OVER_100_USD )
854861 }
855862 return
856863 }
@@ -864,25 +871,31 @@ class AppViewModel @Inject constructor(
864871 utxosToSpend = _sendUiState .value.selectedUtxos,
865872 ).getOrNull() ? : return
866873
867- if (totalFee > BigDecimal .valueOf(amountSats.toLong())
868- .times(BigDecimal (0.5 )).toLong().toUInt()
874+ if (
875+ totalFee > BigDecimal .valueOf(
876+ amountSats.toLong()
877+ ).times(BigDecimal (MAX_FEE_AMOUNT_RATIO )).toLong().toUInt() &&
878+ SanityWarning .FEE_OVER_HALF_VALUE !in _sendUiState .value.confirmedWarnings
869879 ) {
870880 _sendUiState .update {
871- it.copy(showAmountWarningDialog = AmountWarning .FEE_OVER_HALF_VALUE )
881+ it.copy(showSanityWarningDialog = SanityWarning .FEE_OVER_HALF_VALUE )
872882 }
873883 return
874884 }
875885
876- val feeInUsd = currencyRepo.convertSatsToFiat(amountSats.toLong(), " USD" ).getOrNull() ? : return
877- if (feeInUsd.value > BigDecimal (10 )) {
886+ val feeInUsd = currencyRepo.convertSatsToFiat(totalFee.toLong(), " USD" ).getOrNull() ? : return
887+ if (
888+ feeInUsd.value > BigDecimal (TEN_USD ) &&
889+ SanityWarning .FEE_OVER_10_USD !in _sendUiState .value.confirmedWarnings
890+ ) {
878891 _sendUiState .update {
879- it.copy(showAmountWarningDialog = AmountWarning .FEE_OVER_10_USD )
892+ it.copy(showSanityWarningDialog = SanityWarning .FEE_OVER_10_USD )
880893 }
881894 return
882895 }
883896
884897 _sendUiState .update {
885- it.copy(showAmountWarningDialog = null )
898+ it.copy(showSanityWarningDialog = null )
886899 }
887900 }
888901
@@ -1364,20 +1377,21 @@ class AppViewModel @Inject constructor(
13641377 }
13651378 }
13661379
1367- private fun onConfirmAmountWarning () {
1380+ private fun onConfirmAmountWarning (warning : SanityWarning ) {
13681381 viewModelScope.launch {
13691382 _sendUiState .update {
13701383 it.copy(
1371- showAmountWarningDialog = null ,
1372- shouldConfirmPay = true ,
1384+ showSanityWarningDialog = null ,
1385+ confirmedWarnings = it.confirmedWarnings + warning
13731386 )
13741387 }
13751388 }
1389+ onSwipeToPay()
13761390 }
13771391
13781392 private fun onDismissAmountWarning () {
13791393 _sendUiState .update {
1380- it.copy(showAmountWarningDialog = null )
1394+ it.copy(showSanityWarningDialog = null )
13811395 }
13821396 }
13831397
@@ -1392,6 +1406,9 @@ class AppViewModel @Inject constructor(
13921406 companion object {
13931407 private const val TAG = " AppViewModel"
13941408 private const val SEND_AMOUNT_WARNING_THRESHOLD = 100.0
1409+ private const val TEN_USD = 10
1410+ private const val MAX_BALANCE_FRACTION = 0.5
1411+ private const val MAX_FEE_AMOUNT_RATIO = 0.5
13951412 }
13961413}
13971414
@@ -1408,7 +1425,8 @@ data class SendUiState(
14081425 val payMethod : SendMethod = SendMethod .ONCHAIN ,
14091426 val selectedTags : List <String > = listOf(),
14101427 val decodedInvoice : LightningInvoice ? = null ,
1411- val showAmountWarningDialog : AmountWarning ? = null ,
1428+ val showSanityWarningDialog : SanityWarning ? = null ,
1429+ val confirmedWarnings : List <SanityWarning > = listOf(),
14121430 val shouldConfirmPay : Boolean = false ,
14131431 val selectedUtxos : List <SpendableUtxo >? = null ,
14141432 val lnurl : LnurlParams ? = null ,
@@ -1420,7 +1438,7 @@ data class SendUiState(
14201438 val fees : Map <FeeRate , Long > = emptyMap(),
14211439)
14221440
1423- enum class AmountWarning (@StringRes val message : Int , val testTag : String ) {
1441+ enum class SanityWarning (@StringRes val message : Int , val testTag : String ) {
14241442 VALUE_OVER_100_USD (R .string.wallet__send_dialog1, " SendDialog1" ),
14251443 OVER_HALF_BALANCE (R .string.wallet__send_dialog2, " SendDialog2" ),
14261444 FEE_OVER_HALF_VALUE (R .string.wallet__send_dialog3, " SendDialog3" ),
@@ -1471,7 +1489,7 @@ sealed interface SendEvent {
14711489 data object SwipeToPay : SendEvent
14721490 data object SpeedAndFee : SendEvent
14731491 data object PaymentMethodSwitch : SendEvent
1474- data object ConfirmAmountWarning : SendEvent
1492+ data class ConfirmAmountWarning ( val warning : SanityWarning ) : SendEvent
14751493 data object DismissAmountWarning : SendEvent
14761494 data object PayConfirmed : SendEvent
14771495 data object BackToAmount : SendEvent
0 commit comments