@@ -780,6 +780,18 @@ class AppViewModel @Inject constructor(
780780 return
781781 }
782782
783+ extractViableLightningInvoice(invoice.params)?.let { lnInvoice ->
784+ _sendUiState .update {
785+ it.copy(
786+ isAddressInputValid = true ,
787+ isUnified = true ,
788+ decodedInvoice = lnInvoice,
789+ payMethod = SendMethod .LIGHTNING ,
790+ )
791+ }
792+ return
793+ }
794+
783795 val maxSendOnchain = walletRepo.balanceState.value.maxSendOnchainSats
784796
785797 if (maxSendOnchain == 0uL ) {
@@ -805,6 +817,30 @@ class AppViewModel @Inject constructor(
805817 _sendUiState .update { it.copy(isAddressInputValid = true ) }
806818 }
807819
820+ private suspend fun extractViableLightningInvoice (params : Map <String , String >? ): LightningInvoice ? =
821+ params?.get(" lightning" )?.let { bolt11 ->
822+ runCatching { decode(bolt11) }.getOrNull()
823+ ?.let { it as ? Scanner .Lightning }
824+ ?.invoice
825+ ?.takeIf { lnInv ->
826+ if (lnInv.isExpired) {
827+ Logger .debug(
828+ " Lightning invoice expired in unified URI, defaulting to onchain-only" ,
829+ context = TAG
830+ )
831+ return @takeIf false
832+ }
833+ val canSend = lightningRepo.canSend(lnInv.amountSatoshis.coerceAtLeast(1u ))
834+ if (! canSend) {
835+ Logger .debug(
836+ " Cannot pay unified invoice using LN, defaulting to onchain-only" ,
837+ context = TAG
838+ )
839+ }
840+ return @takeIf canSend
841+ }
842+ }
843+
808844 private fun showAddressValidationError (
809845 @StringRes titleRes : Int ,
810846 @StringRes descriptionRes : Int ,
@@ -1055,35 +1091,16 @@ class AppViewModel @Inject constructor(
10551091 )
10561092 return
10571093 }
1094+ val maxSendOnchain = walletRepo.balanceState.value.maxSendOnchainSats
10581095
1059- val lnInvoice: LightningInvoice ? = invoice.params?.get(" lightning" )?.let { bolt11 ->
1060- runCatching { decode(bolt11) }.getOrNull()
1061- ?.let { it as ? Scanner .Lightning }
1062- ?.invoice
1063- ?.takeIf { invoice ->
1064- if (invoice.isExpired) {
1065- Logger .debug(
1066- " Lightning invoice expired in unified URI, defaulting to onchain-only" ,
1067- context = TAG
1068- )
1069- return @takeIf false
1070- }
1071-
1072- // Then check sending capacity
1073- val canSend = lightningRepo.canSend(invoice.amountSatoshis.coerceAtLeast(1u ))
1074- if (! canSend) {
1075- Logger .debug(" Cannot pay unified invoice using LN, defaulting to onchain-only" , context = TAG )
1076- }
1077- return @takeIf canSend
1078- }
1079- }
1096+ val lnInvoice = extractViableLightningInvoice(invoice.params)
10801097 _sendUiState .update {
10811098 it.copy(
10821099 address = invoice.address,
10831100 addressInput = scanResult,
10841101 isAddressInputValid = true ,
10851102 amount = invoice.amountSatoshis,
1086- isUnified = lnInvoice != null ,
1103+ isUnified = lnInvoice != null && invoice.amountSatoshis <= maxSendOnchain && maxSendOnchain > 0u ,
10871104 decodedInvoice = lnInvoice,
10881105 payMethod = lnInvoice?.let { SendMethod .LIGHTNING } ? : SendMethod .ONCHAIN ,
10891106 )
@@ -1109,8 +1126,7 @@ class AppViewModel @Inject constructor(
11091126 }
11101127
11111128 // Check on-chain balance before proceeding to amount screen
1112- val maxSendOnchain = walletRepo.balanceState.value.maxSendOnchainSats
1113- if (maxSendOnchain == 0uL ) {
1129+ if (maxSendOnchain == 0uL && _sendUiState .value.payMethod == SendMethod .ONCHAIN ) {
11141130 toast(
11151131 type = Toast .ToastType .ERROR ,
11161132 title = context.getString(R .string.other__pay_insufficient_savings),
@@ -1121,7 +1137,11 @@ class AppViewModel @Inject constructor(
11211137 }
11221138
11231139 // Check if on-chain invoice amount exceeds available balance
1124- if (invoice.amountSatoshis > 0uL && invoice.amountSatoshis > maxSendOnchain) {
1140+ if (
1141+ invoice.amountSatoshis > 0uL &&
1142+ invoice.amountSatoshis > maxSendOnchain &&
1143+ _sendUiState .value.payMethod == SendMethod .ONCHAIN
1144+ ) {
11251145 val shortfall = invoice.amountSatoshis - maxSendOnchain
11261146 toast(
11271147 type = Toast .ToastType .ERROR ,
0 commit comments