@@ -294,7 +294,7 @@ class AppViewModel @Inject constructor(
294294
295295 SendEvent .SpeedAndFee -> setSendEffect(SendEffect .NavigateToFee )
296296 SendEvent .SwipeToPay -> onSwipeToPay()
297- SendEvent .ConfirmAmountWarning -> onConfirmAmountWarning()
297+ is SendEvent .ConfirmAmountWarning -> onConfirmAmountWarning(it.warning )
298298 SendEvent .DismissAmountWarning -> onDismissAmountWarning()
299299 SendEvent .PayConfirmed -> onConfirmPay()
300300 SendEvent .BackToAmount -> setSendEffect(SendEffect .PopBack (SendRoute .Amount ))
@@ -819,29 +819,36 @@ class AppViewModel @Inject constructor(
819819 val amount = _sendUiState .value.amount
820820
821821 handleSanityChecks(amount)
822- if (_sendUiState .value.showAmountWarningDialog != null ) return @launch // await for dialog UI interaction
822+ if (_sendUiState .value.showSanityWarningDialog != null ) return @launch // await for dialog UI interaction
823823
824824 _sendUiState .update { it.copy(shouldConfirmPay = true ) }
825825 }
826826 }
827827
828828 private suspend fun handleSanityChecks (amountSats : ULong ) {
829- if (_sendUiState .value.showAmountWarningDialog != null ) return
829+ if (_sendUiState .value.showSanityWarningDialog != null ) return
830830
831831 val settings = settingsStore.data.first()
832- val amountInUsd = currencyRepo.convertSatsToFiat(amountSats.toLong(), " USD" ).getOrNull() ? : return
833- if (amountInUsd.value > BigDecimal (SEND_AMOUNT_WARNING_THRESHOLD ) && settings.enableSendAmountWarning) {
832+
833+ if (
834+ amountSats > BigDecimal .valueOf(walletRepo.balanceState.value.totalSats.toLong())
835+ .times(BigDecimal (MAX_BALANCE_FRACTION )).toLong().toUInt() &&
836+ SanityWarning .OVER_HALF_BALANCE !in _sendUiState .value.confirmedWarnings
837+ ) {
834838 _sendUiState .update {
835- it.copy(showAmountWarningDialog = AmountWarning . VALUE_OVER_100_USD )
839+ it.copy(showSanityWarningDialog = SanityWarning . OVER_HALF_BALANCE )
836840 }
837841 return
838842 }
839843
840- if (amountSats > BigDecimal .valueOf(walletRepo.balanceState.value.totalSats.toLong())
841- .times(BigDecimal (0.5 )).toLong().toUInt()
844+ val amountInUsd = currencyRepo.convertSatsToFiat(amountSats.toLong(), " USD" ).getOrNull() ? : return
845+ if (
846+ amountInUsd.value > BigDecimal (SEND_AMOUNT_WARNING_THRESHOLD ) &&
847+ settings.enableSendAmountWarning &&
848+ SanityWarning .VALUE_OVER_100_USD !in _sendUiState .value.confirmedWarnings
842849 ) {
843850 _sendUiState .update {
844- it.copy(showAmountWarningDialog = AmountWarning . OVER_HALF_BALANCE )
851+ it.copy(showSanityWarningDialog = SanityWarning . VALUE_OVER_100_USD )
845852 }
846853 return
847854 }
@@ -855,25 +862,31 @@ class AppViewModel @Inject constructor(
855862 utxosToSpend = _sendUiState .value.selectedUtxos,
856863 ).getOrNull() ? : return
857864
858- if (totalFee > BigDecimal .valueOf(amountSats.toLong())
859- .times(BigDecimal (0.5 )).toLong().toUInt()
865+ if (
866+ totalFee > BigDecimal .valueOf(
867+ amountSats.toLong()
868+ ).times(BigDecimal (MAX_FEE_AMOUNT_RATIO )).toLong().toUInt() &&
869+ SanityWarning .FEE_OVER_HALF_VALUE !in _sendUiState .value.confirmedWarnings
860870 ) {
861871 _sendUiState .update {
862- it.copy(showAmountWarningDialog = AmountWarning .FEE_OVER_HALF_VALUE )
872+ it.copy(showSanityWarningDialog = SanityWarning .FEE_OVER_HALF_VALUE )
863873 }
864874 return
865875 }
866876
867- val feeInUsd = currencyRepo.convertSatsToFiat(amountSats.toLong(), " USD" ).getOrNull() ? : return
868- if (feeInUsd.value > BigDecimal (10 )) {
877+ val feeInUsd = currencyRepo.convertSatsToFiat(totalFee.toLong(), " USD" ).getOrNull() ? : return
878+ if (
879+ feeInUsd.value > BigDecimal (TEN_USD ) &&
880+ SanityWarning .FEE_OVER_10_USD !in _sendUiState .value.confirmedWarnings
881+ ) {
869882 _sendUiState .update {
870- it.copy(showAmountWarningDialog = AmountWarning .FEE_OVER_10_USD )
883+ it.copy(showSanityWarningDialog = SanityWarning .FEE_OVER_10_USD )
871884 }
872885 return
873886 }
874887
875888 _sendUiState .update {
876- it.copy(showAmountWarningDialog = null )
889+ it.copy(showSanityWarningDialog = null )
877890 }
878891 }
879892
@@ -1369,20 +1382,21 @@ class AppViewModel @Inject constructor(
13691382 }
13701383 }
13711384
1372- private fun onConfirmAmountWarning () {
1385+ private fun onConfirmAmountWarning (warning : SanityWarning ) {
13731386 viewModelScope.launch {
13741387 _sendUiState .update {
13751388 it.copy(
1376- showAmountWarningDialog = null ,
1377- shouldConfirmPay = true ,
1389+ showSanityWarningDialog = null ,
1390+ confirmedWarnings = it.confirmedWarnings + warning
13781391 )
13791392 }
13801393 }
1394+ onSwipeToPay()
13811395 }
13821396
13831397 private fun onDismissAmountWarning () {
13841398 _sendUiState .update {
1385- it.copy(showAmountWarningDialog = null )
1399+ it.copy(showSanityWarningDialog = null )
13861400 }
13871401 }
13881402
@@ -1397,6 +1411,9 @@ class AppViewModel @Inject constructor(
13971411 companion object {
13981412 private const val TAG = " AppViewModel"
13991413 private const val SEND_AMOUNT_WARNING_THRESHOLD = 100.0
1414+ private const val TEN_USD = 10
1415+ private const val MAX_BALANCE_FRACTION = 0.5
1416+ private const val MAX_FEE_AMOUNT_RATIO = 0.5
14001417 }
14011418}
14021419
@@ -1413,7 +1430,8 @@ data class SendUiState(
14131430 val payMethod : SendMethod = SendMethod .ONCHAIN ,
14141431 val selectedTags : List <String > = listOf(),
14151432 val decodedInvoice : LightningInvoice ? = null ,
1416- val showAmountWarningDialog : AmountWarning ? = null ,
1433+ val showSanityWarningDialog : SanityWarning ? = null ,
1434+ val confirmedWarnings : List <SanityWarning > = listOf(),
14171435 val shouldConfirmPay : Boolean = false ,
14181436 val selectedUtxos : List <SpendableUtxo >? = null ,
14191437 val lnurl : LnurlParams ? = null ,
@@ -1425,7 +1443,7 @@ data class SendUiState(
14251443 val fees : Map <FeeRate , Long > = emptyMap(),
14261444)
14271445
1428- enum class AmountWarning (@StringRes val message : Int , val testTag : String ) {
1446+ enum class SanityWarning (@StringRes val message : Int , val testTag : String ) {
14291447 VALUE_OVER_100_USD (R .string.wallet__send_dialog1, " SendDialog1" ),
14301448 OVER_HALF_BALANCE (R .string.wallet__send_dialog2, " SendDialog2" ),
14311449 FEE_OVER_HALF_VALUE (R .string.wallet__send_dialog3, " SendDialog3" ),
@@ -1476,7 +1494,7 @@ sealed interface SendEvent {
14761494 data object SwipeToPay : SendEvent
14771495 data object SpeedAndFee : SendEvent
14781496 data object PaymentMethodSwitch : SendEvent
1479- data object ConfirmAmountWarning : SendEvent
1497+ data class ConfirmAmountWarning ( val warning : SanityWarning ) : SendEvent
14801498 data object DismissAmountWarning : SendEvent
14811499 data object PayConfirmed : SendEvent
14821500 data object BackToAmount : SendEvent
0 commit comments