@@ -77,6 +77,8 @@ import to.bitkit.ext.channelId
7777import to.bitkit.ext.claimableAtHeight
7878import to.bitkit.ext.getClipboardText
7979import to.bitkit.ext.getSatsPerVByteFor
80+ import to.bitkit.ext.callbackAmountMsats
81+ import to.bitkit.ext.isFixedAmount
8082import to.bitkit.ext.maxSendableSat
8183import to.bitkit.ext.maxWithdrawableSat
8284import to.bitkit.ext.minSendableSat
@@ -1219,7 +1221,7 @@ class AppViewModel @Inject constructor(
12191221 val maxSendable = maxSendableLightningSats()
12201222 when (val lnurl = _sendUiState .value.lnurl) {
12211223 null -> amount <= maxSendable && lightningRepo.canSend(amount)
1222- is LnurlParams .LnurlWithdraw -> amount < lnurl.data.maxWithdrawableSat()
1224+ is LnurlParams .LnurlWithdraw -> amount <= lnurl.data.maxWithdrawableSat()
12231225 is LnurlParams .LnurlPay -> {
12241226 val maxSat = lnurl.data.maxSendableSat()
12251227 amount <= maxSat && amount <= maxSendable && lightningRepo.canSend(amount)
@@ -1465,10 +1467,10 @@ class AppViewModel @Inject constructor(
14651467 private suspend fun onScanLnurlPay (data : LnurlPayData ) {
14661468 Logger .debug(" LNURL: $data " , context = TAG )
14671469
1468- val minSendable = data.minSendableSat ()
1469- val maxSendable = data.maxSendableSat ()
1470+ val isFixed = data.isFixedAmount ()
1471+ val displaySats = data.minSendableSat ()
14701472
1471- if (! lightningRepo.canSend(minSendable )) {
1473+ if (! lightningRepo.canSend(displaySats.coerceAtLeast( 1u ) )) {
14721474 toast(
14731475 type = Toast .ToastType .WARNING ,
14741476 title = context.getString(R .string.other__lnurl_pay_error),
@@ -1477,8 +1479,7 @@ class AppViewModel @Inject constructor(
14771479 return
14781480 }
14791481
1480- val hasAmount = minSendable == maxSendable && minSendable > 0u
1481- val initialAmount = if (hasAmount) minSendable else 0u
1482+ val initialAmount = if (isFixed) displaySats else 0u
14821483
14831484 _sendUiState .update {
14841485 it.copy(
@@ -1488,10 +1489,10 @@ class AppViewModel @Inject constructor(
14881489 )
14891490 }
14901491
1491- if (hasAmount ) {
1492- Logger .info(" Found amount $ $minSendable in lnurlPay, proceeding with payment" , context = TAG )
1492+ if (isFixed ) {
1493+ Logger .info(" Found fixed amount ' $displaySats ' sats in lnurlPay, proceeding with payment" , context = TAG )
14931494
1494- val quickPayHandled = handleQuickPayIfApplicable(amountSats = minSendable , lnurlPay = data)
1495+ val quickPayHandled = handleQuickPayIfApplicable(amountSats = displaySats , lnurlPay = data)
14951496 if (quickPayHandled) return
14961497
14971498 if (isMainScanner) {
@@ -1513,10 +1514,11 @@ class AppViewModel @Inject constructor(
15131514 private suspend fun onScanLnurlWithdraw (data : LnurlWithdrawData ) {
15141515 Logger .debug(" LNURL: $data " , context = TAG )
15151516
1517+ val isFixed = data.isFixedAmount()
15161518 val minWithdrawable = data.minWithdrawableSat()
15171519 val maxWithdrawable = data.maxWithdrawableSat()
15181520
1519- if (minWithdrawable > maxWithdrawable) {
1521+ if (! isFixed && minWithdrawable > maxWithdrawable) {
15201522 toast(
15211523 type = Toast .ToastType .WARNING ,
15221524 title = context.getString(R .string.other__lnurl_withdr_error),
@@ -1525,15 +1527,17 @@ class AppViewModel @Inject constructor(
15251527 return
15261528 }
15271529
1530+ val displayAmount = minWithdrawable
1531+
15281532 _sendUiState .update {
15291533 it.copy(
15301534 payMethod = SendMethod .LIGHTNING ,
1531- amount = minWithdrawable ,
1535+ amount = displayAmount ,
15321536 lnurl = LnurlParams .LnurlWithdraw (data = data)
15331537 )
15341538 }
15351539
1536- if (minWithdrawable == maxWithdrawable) {
1540+ if (isFixed || minWithdrawable == maxWithdrawable) {
15371541 delay(TRANSITION_SCREEN_MS )
15381542 if (isMainScanner) {
15391543 showSheet(Sheet .Send (SendRoute .WithdrawConfirm ))
@@ -1642,7 +1646,11 @@ class AppViewModel @Inject constructor(
16421646
16431647 val quickPayData: QuickPayData = when {
16441648 lnurlPay != null -> {
1645- QuickPayData .LnurlPay (sats = amountSats, callback = lnurlPay.callback)
1649+ QuickPayData .LnurlPay (
1650+ sats = amountSats,
1651+ callback = lnurlPay.callback,
1652+ amountMsats = lnurlPay.callbackAmountMsats(amountSats),
1653+ )
16461654 }
16471655
16481656 else -> {
@@ -1766,9 +1774,10 @@ class AppViewModel @Inject constructor(
17661774 val isLnurlPay = lnurl is LnurlParams .LnurlPay
17671775
17681776 if (isLnurlPay) {
1777+ val amountMsats = lnurl.data.callbackAmountMsats(amount)
17691778 lightningRepo.fetchLnurlInvoice(
17701779 callbackUrl = lnurl.data.callback,
1771- amountSats = amount ,
1780+ amountMsats = amountMsats ,
17721781 comment = _sendUiState .value.comment.takeIf { it.isNotEmpty() },
17731782 ).onSuccess { invoice ->
17741783 _sendUiState .update {
@@ -1816,8 +1825,8 @@ class AppViewModel @Inject constructor(
18161825 val decodedInvoice = requireNotNull(_sendUiState .value.decodedInvoice)
18171826 val bolt11 = decodedInvoice.bolt11
18181827
1819- // Determine if we should override amount
1820- val paymentAmount = decodedInvoice.amountSatoshis.takeIf { it > 0uL } ? : amount
1828+ val paymentAmount = if (decodedInvoice.amountSatoshis > 0uL ) null else amount
1829+ val displayAmountSats = decodedInvoice.amountSatoshis.takeIf { it > 0uL } ? : amount ? : 0uL
18211830
18221831 val tags = _sendUiState .value.selectedTags
18231832 var createdMetadataPaymentId: String? = null
@@ -1845,14 +1854,14 @@ class AppViewModel @Inject constructor(
18451854 type = NewTransactionSheetType .LIGHTNING ,
18461855 direction = NewTransactionSheetDirection .SENT ,
18471856 paymentHashOrTxId = actualPaymentHash,
1848- sats = paymentAmount .toLong(), // TODO Add fee when available
1857+ sats = displayAmountSats .toLong(), // TODO Add fee when available
18491858 ),
18501859 )
18511860 }.onFailure {
18521861 if (it is PaymentPendingException ) {
18531862 Logger .info(" Lightning payment pending" , context = TAG )
18541863 pendingPaymentRepo.track(it.paymentHash)
1855- setSendEffect(SendEffect .NavigateToPending (it.paymentHash, paymentAmount .toLong()))
1864+ setSendEffect(SendEffect .NavigateToPending (it.paymentHash, displayAmountSats .toLong()))
18561865 return @onFailure
18571866 }
18581867 // Delete pre-activity metadata on failure
@@ -1877,19 +1886,23 @@ class AppViewModel @Inject constructor(
18771886 return @launch
18781887 }
18791888
1880- _sendUiState .update {
1881- it.copy (
1882- amount = it.amount.coerceAtLeast(
1883- ( lnurl.data.minWithdrawable ? : 0u ) / 1000u
1884- )
1889+ val invoice = if (lnurl.data.isFixedAmount()) {
1890+ lightningRepo.createInvoiceMsats (
1891+ amountMsats = lnurl.data.maxWithdrawable,
1892+ description = lnurl.data.defaultDescription,
1893+ expirySeconds = 3600u ,
18851894 )
1886- }
1887-
1888- val invoice = lightningRepo.createInvoice(
1889- amountSats = _sendUiState .value.amount,
1890- description = lnurl.data.defaultDescription,
1891- expirySeconds = 3600u ,
1892- ).getOrNull()
1895+ } else {
1896+ val withdrawAmountSats = _sendUiState .value.amount.coerceAtLeast(
1897+ (lnurl.data.minWithdrawable ? : 0u ) / 1000u
1898+ )
1899+ _sendUiState .update { it.copy(amount = withdrawAmountSats) }
1900+ lightningRepo.createInvoice(
1901+ amountSats = withdrawAmountSats,
1902+ description = lnurl.data.defaultDescription,
1903+ expirySeconds = 3600u ,
1904+ )
1905+ }.getOrNull()
18931906
18941907 if (invoice == null ) {
18951908 setSendEffect(SendEffect .NavigateToWithdrawError )
@@ -2630,6 +2643,6 @@ sealed interface QuickPayData {
26302643 data class Bolt11 (override val sats : ULong , val bolt11 : String ) : QuickPayData
26312644
26322645 @Stable
2633- data class LnurlPay (override val sats : ULong , val callback : String ) : QuickPayData
2646+ data class LnurlPay (override val sats : ULong , val callback : String , val amountMsats : ULong ) : QuickPayData
26342647}
26352648// endregion
0 commit comments